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...@@ -292,7 +292,7 @@ set(ZIG0_SOURCES
292292
293set(STAGE1_SOURCES293set(STAGE1_SOURCES
294 "${CMAKE_SOURCE_DIR}/src/stage1/analyze.cpp"294 "${CMAKE_SOURCE_DIR}/src/stage1/analyze.cpp"
295 "${CMAKE_SOURCE_DIR}/src/stage1/ast_render.cpp"295 "${CMAKE_SOURCE_DIR}/src/stage1/astgen.cpp"
296 "${CMAKE_SOURCE_DIR}/src/stage1/bigfloat.cpp"296 "${CMAKE_SOURCE_DIR}/src/stage1/bigfloat.cpp"
297 "${CMAKE_SOURCE_DIR}/src/stage1/bigint.cpp"297 "${CMAKE_SOURCE_DIR}/src/stage1/bigint.cpp"
298 "${CMAKE_SOURCE_DIR}/src/stage1/buffer.cpp"298 "${CMAKE_SOURCE_DIR}/src/stage1/buffer.cpp"
...@@ -307,11 +307,11 @@ set(STAGE1_SOURCES...@@ -307,11 +307,11 @@ set(STAGE1_SOURCES
307 "${CMAKE_SOURCE_DIR}/src/stage1/os.cpp"307 "${CMAKE_SOURCE_DIR}/src/stage1/os.cpp"
308 "${CMAKE_SOURCE_DIR}/src/stage1/parser.cpp"308 "${CMAKE_SOURCE_DIR}/src/stage1/parser.cpp"
309 "${CMAKE_SOURCE_DIR}/src/stage1/range_set.cpp"309 "${CMAKE_SOURCE_DIR}/src/stage1/range_set.cpp"
310 "${CMAKE_SOURCE_DIR}/src/stage1/softfloat_ext.cpp"
310 "${CMAKE_SOURCE_DIR}/src/stage1/stage1.cpp"311 "${CMAKE_SOURCE_DIR}/src/stage1/stage1.cpp"
311 "${CMAKE_SOURCE_DIR}/src/stage1/target.cpp"312 "${CMAKE_SOURCE_DIR}/src/stage1/target.cpp"
312 "${CMAKE_SOURCE_DIR}/src/stage1/tokenizer.cpp"313 "${CMAKE_SOURCE_DIR}/src/stage1/tokenizer.cpp"
313 "${CMAKE_SOURCE_DIR}/src/stage1/util.cpp"314 "${CMAKE_SOURCE_DIR}/src/stage1/util.cpp"
314 "${CMAKE_SOURCE_DIR}/src/stage1/softfloat_ext.cpp"
315)315)
316set(OPTIMIZED_C_SOURCES316set(OPTIMIZED_C_SOURCES
317 "${CMAKE_SOURCE_DIR}/src/stage1/parse_f128.c"317 "${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...@@ -107,6 +107,7 @@ pub fn parseAppend(buf: *std.ArrayList(u8), bytes: []const u8) error{OutOfMemory
107 const hex_str = slice[index + 2 .. index_end];107 const hex_str = slice[index + 2 .. index_end];
108 if (std.fmt.parseUnsigned(u32, hex_str, 16)) |uint| {108 if (std.fmt.parseUnsigned(u32, hex_str, 16)) |uint| {
109 if (uint <= 0x10ffff) {109 if (uint <= 0x10ffff) {
110 // TODO this incorrectly depends on endianness
110 try buf.appendSlice(std.mem.toBytes(uint)[0..]);111 try buf.appendSlice(std.mem.toBytes(uint)[0..]);
111 state = State.Start;112 state = State.Start;
112 index = index_end; // loop-header increments113 index = index_end; // loop-header increments
src/stage1.zig+2
...@@ -252,6 +252,8 @@ const Error = extern enum {...@@ -252,6 +252,8 @@ const Error = extern enum {
252 ZigIsTheCCompiler,252 ZigIsTheCCompiler,
253 FileBusy,253 FileBusy,
254 Locked,254 Locked,
255 InvalidCharacter,
256 UnicodePointTooLarge,
255};257};
256258
257// ABI warning259// ABI warning
src/stage1/all_types.hpp+60-118
...@@ -38,7 +38,7 @@ struct IrInstGenCast;...@@ -38,7 +38,7 @@ struct IrInstGenCast;
38struct IrInstGenAlloca;38struct IrInstGenAlloca;
39struct IrInstGenCall;39struct IrInstGenCall;
40struct IrInstGenAwait;40struct IrInstGenAwait;
41struct IrBasicBlockSrc;41struct Stage1ZirBasicBlock;
42struct IrBasicBlockGen;42struct IrBasicBlockGen;
43struct ScopeDecls;43struct ScopeDecls;
44struct ZigWindowsSDK;44struct ZigWindowsSDK;
...@@ -51,7 +51,7 @@ struct ResultLocPeerParent;...@@ -51,7 +51,7 @@ struct ResultLocPeerParent;
51struct ResultLocBitCast;51struct ResultLocBitCast;
52struct ResultLocCast;52struct ResultLocCast;
53struct ResultLocReturn;53struct ResultLocReturn;
54struct IrExecutableGen;54struct Stage1Air;
5555
56enum FileExt {56enum FileExt {
57 FileExtUnknown,57 FileExtUnknown,
...@@ -110,51 +110,33 @@ enum X64CABIClass {...@@ -110,51 +110,33 @@ enum X64CABIClass {
110 X64CABIClass_SSE,110 X64CABIClass_SSE,
111};111};
112112
113struct IrExecutableSrc {113struct Stage1Zir {
114 ZigList<IrBasicBlockSrc *> basic_block_list;114 ZigList<Stage1ZirBasicBlock *> basic_block_list;
115 Buf *name;115 Buf *name;
116 ZigFn *name_fn;116 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;
126 Scope *begin_scope;117 Scope *begin_scope;
127 ErrorMsg *first_err_trace_msg;118 ErrorMsg *first_err_trace_msg;
128 ZigList<Tld *> tld_list;119 ZigList<Tld *> tld_list;
129120
130 bool is_inline;121 bool is_inline;
131 bool is_generic_instantiation;
132 bool need_err_code_spill;122 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();
137};123};
138124
139struct IrExecutableGen {125struct Stage1Air {
140 ZigList<IrBasicBlockGen *> basic_block_list;126 ZigList<IrBasicBlockGen *> basic_block_list;
141 Buf *name;127 Buf *name;
142 ZigFn *name_fn;128 ZigFn *name_fn;
143 size_t mem_slot_count;129 size_t mem_slot_count;
144 size_t next_debug_id;130 size_t next_debug_id;
145 size_t *backward_branch_count;
146 size_t *backward_branch_quota;
147 ZigFn *fn_entry;
148 Buf *c_import_buf;131 Buf *c_import_buf;
149 AstNode *source_node;132 AstNode *source_node;
150 IrExecutableGen *parent_exec;133 Stage1Air *parent_exec;
151 IrExecutableSrc *source_exec;134 Stage1Zir *source_exec;
152 Scope *begin_scope;135 Scope *begin_scope;
153 ErrorMsg *first_err_trace_msg;136 ErrorMsg *first_err_trace_msg;
154 ZigList<Tld *> tld_list;137 ZigList<Tld *> tld_list;
155138
156 bool is_inline;139 bool is_inline;
157 bool is_generic_instantiation;
158 bool need_err_code_spill;140 bool need_err_code_spill;
159141
160 // This is a function for use in the debugger to print142 // This is a function for use in the debugger to print
...@@ -670,7 +652,7 @@ enum NodeType {...@@ -670,7 +652,7 @@ enum NodeType {
670 NodeTypeIntLiteral,652 NodeTypeIntLiteral,
671 NodeTypeStringLiteral,653 NodeTypeStringLiteral,
672 NodeTypeCharLiteral,654 NodeTypeCharLiteral,
673 NodeTypeSymbol,655 NodeTypeIdentifier,
674 NodeTypePrefixOpExpr,656 NodeTypePrefixOpExpr,
675 NodeTypePointerType,657 NodeTypePointerType,
676 NodeTypeFnCallExpr,658 NodeTypeFnCallExpr,
...@@ -710,6 +692,7 @@ enum NodeType {...@@ -710,6 +692,7 @@ enum NodeType {
710 NodeTypeAwaitExpr,692 NodeTypeAwaitExpr,
711 NodeTypeSuspend,693 NodeTypeSuspend,
712 NodeTypeAnyFrameType,694 NodeTypeAnyFrameType,
695 // main_token points to the identifier.
713 NodeTypeEnumLiteral,696 NodeTypeEnumLiteral,
714 NodeTypeAnyTypeField,697 NodeTypeAnyTypeField,
715};698};
...@@ -733,7 +716,8 @@ struct AstNodeFnProto {...@@ -733,7 +716,8 @@ struct AstNodeFnProto {
733 AstNode *section_expr;716 AstNode *section_expr;
734 // populated if the "callconv(S)" is present717 // populated if the "callconv(S)" is present
735 AstNode *callconv_expr;718 AstNode *callconv_expr;
736 Buf doc_comments;719
720 TokenIndex doc_comments;
737721
738 // This is set based only on the existence of a noinline or inline keyword.722 // This is set based only on the existence of a noinline or inline keyword.
739 // This is then resolved to an is_noinline bool and (potentially .Inline)723 // This is then resolved to an is_noinline bool and (potentially .Inline)
...@@ -755,8 +739,8 @@ struct AstNodeFnDef {...@@ -755,8 +739,8 @@ struct AstNodeFnDef {
755struct AstNodeParamDecl {739struct AstNodeParamDecl {
756 Buf *name;740 Buf *name;
757 AstNode *type;741 AstNode *type;
758 Token *anytype_token;742 TokenIndex doc_comments;
759 Buf doc_comments;743 TokenIndex anytype_token;
760 bool is_noalias;744 bool is_noalias;
761 bool is_comptime;745 bool is_comptime;
762 bool is_var_args;746 bool is_var_args;
...@@ -799,9 +783,9 @@ struct AstNodeVariableDeclaration {...@@ -799,9 +783,9 @@ struct AstNodeVariableDeclaration {
799 AstNode *align_expr;783 AstNode *align_expr;
800 // populated if the "section(S)" is present784 // populated if the "section(S)" is present
801 AstNode *section_expr;785 AstNode *section_expr;
802 Token *threadlocal_tok;786 TokenIndex doc_comments;
803 Buf doc_comments;
804787
788 TokenIndex threadlocal_tok;
805 VisibMod visib_mod;789 VisibMod visib_mod;
806 bool is_const;790 bool is_const;
807 bool is_comptime;791 bool is_comptime;
...@@ -935,13 +919,14 @@ struct AstNodePrefixOpExpr {...@@ -935,13 +919,14 @@ struct AstNodePrefixOpExpr {
935};919};
936920
937struct AstNodePointerType {921struct 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
939 AstNode *sentinel;927 AstNode *sentinel;
940 AstNode *align_expr;928 AstNode *align_expr;
941 BigInt *bit_offset_start;
942 BigInt *host_int_bytes;
943 AstNode *op_expr;929 AstNode *op_expr;
944 Token *allow_zero_token;
945 bool is_const;930 bool is_const;
946 bool is_volatile;931 bool is_volatile;
947};932};
...@@ -956,7 +941,7 @@ struct AstNodeArrayType {...@@ -956,7 +941,7 @@ struct AstNodeArrayType {
956 AstNode *sentinel;941 AstNode *sentinel;
957 AstNode *child_type;942 AstNode *child_type;
958 AstNode *align_expr;943 AstNode *align_expr;
959 Token *allow_zero_token;944 TokenIndex allow_zero_token;
960 bool is_const;945 bool is_const;
961 bool is_volatile;946 bool is_volatile;
962};947};
...@@ -974,11 +959,11 @@ struct AstNodeIfBoolExpr {...@@ -974,11 +959,11 @@ struct AstNodeIfBoolExpr {
974959
975struct AstNodeTryExpr {960struct AstNodeTryExpr {
976 Buf *var_symbol;961 Buf *var_symbol;
977 bool var_is_ptr;
978 AstNode *target_node;962 AstNode *target_node;
979 AstNode *then_node;963 AstNode *then_node;
980 AstNode *else_node;964 AstNode *else_node;
981 Buf *err_symbol;965 Buf *err_symbol;
966 bool var_is_ptr;
982};967};
983968
984struct AstNodeTestExpr {969struct AstNodeTestExpr {
...@@ -993,12 +978,12 @@ struct AstNodeWhileExpr {...@@ -993,12 +978,12 @@ struct AstNodeWhileExpr {
993 Buf *name;978 Buf *name;
994 AstNode *condition;979 AstNode *condition;
995 Buf *var_symbol;980 Buf *var_symbol;
996 bool var_is_ptr;
997 AstNode *continue_expr;981 AstNode *continue_expr;
998 AstNode *body;982 AstNode *body;
999 AstNode *else_node;983 AstNode *else_node;
1000 Buf *err_symbol;984 Buf *err_symbol;
1001 bool is_inline;985 bool is_inline;
986 bool var_is_ptr;
1002};987};
1003988
1004struct AstNodeForExpr {989struct AstNodeForExpr {
...@@ -1070,7 +1055,7 @@ struct AsmToken {...@@ -1070,7 +1055,7 @@ struct AsmToken {
1070};1055};
10711056
1072struct AstNodeAsmExpr {1057struct AstNodeAsmExpr {
1073 Token *volatile_token;1058 TokenIndex volatile_token;
1074 AstNode *asm_template;1059 AstNode *asm_template;
1075 ZigList<AsmOutput*> output_list;1060 ZigList<AsmOutput*> output_list;
1076 ZigList<AsmInput*> input_list;1061 ZigList<AsmInput*> input_list;
...@@ -1094,7 +1079,7 @@ struct AstNodeContainerDecl {...@@ -1094,7 +1079,7 @@ struct AstNodeContainerDecl {
1094 AstNode *init_arg_expr; // enum(T), struct(endianness), or union(T), or union(enum(T))1079 AstNode *init_arg_expr; // enum(T), struct(endianness), or union(T), or union(enum(T))
1095 ZigList<AstNode *> fields;1080 ZigList<AstNode *> fields;
1096 ZigList<AstNode *> decls;1081 ZigList<AstNode *> decls;
1097 Buf doc_comments;1082 TokenIndex doc_comments;
10981083
1099 ContainerKind kind;1084 ContainerKind kind;
1100 ContainerLayout layout;1085 ContainerLayout layout;
...@@ -1103,7 +1088,7 @@ struct AstNodeContainerDecl {...@@ -1103,7 +1088,7 @@ struct AstNodeContainerDecl {
1103};1088};
11041089
1105struct AstNodeErrorSetField {1090struct AstNodeErrorSetField {
1106 Buf doc_comments;1091 TokenIndex doc_comments;
1107 AstNode *field_name;1092 AstNode *field_name;
1108};1093};
11091094
...@@ -1118,28 +1103,8 @@ struct AstNodeStructField {...@@ -1118,28 +1103,8 @@ struct AstNodeStructField {
1118 AstNode *value;1103 AstNode *value;
1119 // populated if the "align(A)" is present1104 // populated if the "align(A)" is present
1120 AstNode *align_expr;1105 AstNode *align_expr;
1121 Buf doc_comments;1106 TokenIndex doc_comments;
1122 Token *comptime_token;1107 TokenIndex 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;
1143};1108};
11441109
1145struct AstNodeStructValueField {1110struct AstNodeStructValueField {
...@@ -1158,17 +1123,12 @@ struct AstNodeContainerInitExpr {...@@ -1158,17 +1123,12 @@ struct AstNodeContainerInitExpr {
1158 ContainerInitKind kind;1123 ContainerInitKind kind;
1159};1124};
11601125
1161struct AstNodeNullLiteral {1126struct AstNodeIdentifier {
1162};1127 Buf *name;
1163
1164struct AstNodeUndefinedLiteral {
1165};
1166
1167struct AstNodeThisLiteral {
1168};1128};
11691129
1170struct AstNodeSymbolExpr {1130struct AstNodeEnumLiteral {
1171 Buf *symbol;1131 Buf *name;
1172};1132};
11731133
1174struct AstNodeBoolLiteral {1134struct AstNodeBoolLiteral {
...@@ -1188,13 +1148,6 @@ struct AstNodeContinueExpr {...@@ -1188,13 +1148,6 @@ struct AstNodeContinueExpr {
1188 Buf *name;1148 Buf *name;
1189};1149};
11901150
1191struct AstNodeUnreachableExpr {
1192};
1193
1194
1195struct AstNodeErrorType {
1196};
1197
1198struct AstNodeAwaitExpr {1151struct AstNodeAwaitExpr {
1199 AstNode *expr;1152 AstNode *expr;
1200};1153};
...@@ -1207,16 +1160,10 @@ struct AstNodeAnyFrameType {...@@ -1207,16 +1160,10 @@ struct AstNodeAnyFrameType {
1207 AstNode *payload_type; // can be NULL1160 AstNode *payload_type; // can be NULL
1208};1161};
12091162
1210struct AstNodeEnumLiteral {
1211 Token *period;
1212 Token *identifier;
1213};
1214
1215struct AstNode {1163struct AstNode {
1216 enum NodeType type;1164 enum NodeType type;
1165 TokenIndex main_token;
1217 bool already_traced_this_node;1166 bool already_traced_this_node;
1218 size_t line;
1219 size_t column;
1220 ZigType *owner;1167 ZigType *owner;
1221 union {1168 union {
1222 AstNodeFnDef fn_def;1169 AstNodeFnDef fn_def;
...@@ -1252,29 +1199,24 @@ struct AstNode {...@@ -1252,29 +1199,24 @@ struct AstNode {
1252 AstNodePtrDerefExpr ptr_deref_expr;1199 AstNodePtrDerefExpr ptr_deref_expr;
1253 AstNodeContainerDecl container_decl;1200 AstNodeContainerDecl container_decl;
1254 AstNodeStructField struct_field;1201 AstNodeStructField struct_field;
1255 AstNodeStringLiteral string_literal;
1256 AstNodeCharLiteral char_literal;
1257 AstNodeFloatLiteral float_literal;
1258 AstNodeIntLiteral int_literal;
1259 AstNodeContainerInitExpr container_init_expr;1202 AstNodeContainerInitExpr container_init_expr;
1260 AstNodeStructValueField struct_val_field;1203 AstNodeStructValueField struct_val_field;
1261 AstNodeNullLiteral null_literal;
1262 AstNodeUndefinedLiteral undefined_literal;
1263 AstNodeThisLiteral this_literal;
1264 AstNodeSymbolExpr symbol_expr;
1265 AstNodeBoolLiteral bool_literal;1204 AstNodeBoolLiteral bool_literal;
1266 AstNodeBreakExpr break_expr;1205 AstNodeBreakExpr break_expr;
1267 AstNodeContinueExpr continue_expr;1206 AstNodeContinueExpr continue_expr;
1268 AstNodeUnreachableExpr unreachable_expr;
1269 AstNodeArrayType array_type;1207 AstNodeArrayType array_type;
1270 AstNodeInferredArrayType inferred_array_type;1208 AstNodeInferredArrayType inferred_array_type;
1271 AstNodeErrorType error_type;
1272 AstNodeErrorSetDecl err_set_decl;1209 AstNodeErrorSetDecl err_set_decl;
1273 AstNodeErrorSetField err_set_field;1210 AstNodeErrorSetField err_set_field;
1274 AstNodeResumeExpr resume_expr;1211 AstNodeResumeExpr resume_expr;
1275 AstNodeAwaitExpr await_expr;1212 AstNodeAwaitExpr await_expr;
1276 AstNodeSuspend suspend;1213 AstNodeSuspend suspend;
1277 AstNodeAnyFrameType anyframe_type;1214 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;
1278 AstNodeEnumLiteral enum_literal;1220 AstNodeEnumLiteral enum_literal;
1279 } data;1221 } data;
12801222
...@@ -1409,9 +1351,11 @@ struct ZigPackage {...@@ -1409,9 +1351,11 @@ struct ZigPackage {
1409struct RootStruct {1351struct RootStruct {
1410 ZigPackage *package;1352 ZigPackage *package;
1411 Buf *path; // relative to root_package->root_src_dir1353 Buf *path; // relative to root_package->root_src_dir
1412 ZigList<size_t> *line_offsets;
1413 Buf *source_code;1354 Buf *source_code;
1414 ZigLLVMDIFile *di_file;1355 ZigLLVMDIFile *di_file;
1356 size_t token_count;
1357 TokenId *token_ids;
1358 TokenLoc *token_locs;
1415};1359};
14161360
1417enum StructSpecial {1361enum StructSpecial {
...@@ -1703,10 +1647,9 @@ struct ZigFn {...@@ -1703,10 +1647,9 @@ struct ZigFn {
1703 // in the case of async functions this is the implicit return type according to the1647 // in the case of async functions this is the implicit return type according to the
1704 // zig source code, not according to zig ir1648 // zig source code, not according to zig ir
1705 ZigType *src_implicit_return_type;1649 ZigType *src_implicit_return_type;
1706 IrExecutableSrc *ir_executable;1650 Stage1Zir *stage1_zir;
1707 IrExecutableGen analyzed_executable;1651 Stage1Air analyzed_executable;
1708 size_t prealloc_bbc;1652 size_t branch_quota;
1709 size_t prealloc_backward_branch_quota;
1710 AstNode **param_source_nodes;1653 AstNode **param_source_nodes;
1711 Buf **param_names;1654 Buf **param_names;
1712 IrInstGen *err_code_spill;1655 IrInstGen *err_code_spill;
...@@ -2326,11 +2269,11 @@ struct ScopeBlock {...@@ -2326,11 +2269,11 @@ struct ScopeBlock {
2326 Scope base;2269 Scope base;
23272270
2328 Buf *name;2271 Buf *name;
2329 IrBasicBlockSrc *end_block;2272 Stage1ZirBasicBlock *end_block;
2330 IrInstSrc *is_comptime;2273 IrInstSrc *is_comptime;
2331 ResultLocPeerParent *peer_parent;2274 ResultLocPeerParent *peer_parent;
2332 ZigList<IrInstSrc *> *incoming_values;2275 ZigList<IrInstSrc *> *incoming_values;
2333 ZigList<IrBasicBlockSrc *> *incoming_blocks;2276 ZigList<Stage1ZirBasicBlock *> *incoming_blocks;
23342277
2335 AstNode *safety_set_node;2278 AstNode *safety_set_node;
2336 AstNode *fast_math_set_node;2279 AstNode *fast_math_set_node;
...@@ -2382,11 +2325,11 @@ struct ScopeLoop {...@@ -2382,11 +2325,11 @@ struct ScopeLoop {
23822325
2383 LVal lval;2326 LVal lval;
2384 Buf *name;2327 Buf *name;
2385 IrBasicBlockSrc *break_block;2328 Stage1ZirBasicBlock *break_block;
2386 IrBasicBlockSrc *continue_block;2329 Stage1ZirBasicBlock *continue_block;
2387 IrInstSrc *is_comptime;2330 IrInstSrc *is_comptime;
2388 ZigList<IrInstSrc *> *incoming_values;2331 ZigList<IrInstSrc *> *incoming_values;
2389 ZigList<IrBasicBlockSrc *> *incoming_blocks;2332 ZigList<Stage1ZirBasicBlock *> *incoming_blocks;
2390 ResultLocPeerParent *peer_parent;2333 ResultLocPeerParent *peer_parent;
2391 ScopeExpr *spill_scope;2334 ScopeExpr *spill_scope;
23922335
...@@ -2497,7 +2440,7 @@ enum AtomicRmwOp {...@@ -2497,7 +2440,7 @@ enum AtomicRmwOp {
2497// to another basic block.2440// to another basic block.
2498// Phi instructions must be first in a basic block.2441// Phi instructions must be first in a basic block.
2499// The last instruction in a basic block must be of type unreachable.2442// The last instruction in a basic block must be of type unreachable.
2500struct IrBasicBlockSrc {2443struct Stage1ZirBasicBlock {
2501 ZigList<IrInstSrc *> instruction_list;2444 ZigList<IrInstSrc *> instruction_list;
2502 IrBasicBlockGen *child;2445 IrBasicBlockGen *child;
2503 Scope *scope;2446 Scope *scope;
...@@ -2772,8 +2715,7 @@ enum IrInstGenId {...@@ -2772,8 +2715,7 @@ enum IrInstGenId {
2772 IrInstGenIdExtern,2715 IrInstGenIdExtern,
2773};2716};
27742717
2775// Common fields between IrInstSrc and IrInstGen. This allows future passes2718// Common fields between IrInstSrc and IrInstGen.
2776// after pass2 to be added to zig.
2777struct IrInst {2719struct IrInst {
2778 // if ref_count is zero and the instruction has no side effects,2720 // if ref_count is zero and the instruction has no side effects,
2779 // the instruction can be omitted in codegen2721 // the instruction can be omitted in codegen
...@@ -2801,7 +2743,7 @@ struct IrInstSrc {...@@ -2801,7 +2743,7 @@ struct IrInstSrc {
2801 // can find the instruction that corresponds to this value in the "new ir"2743 // can find the instruction that corresponds to this value in the "new ir"
2802 // with this child field.2744 // with this child field.
2803 IrInstGen *child;2745 IrInstGen *child;
2804 IrBasicBlockSrc *owner_bb;2746 Stage1ZirBasicBlock *owner_bb;
28052747
2806 // for debugging purposes, these are useful to call to inspect the instruction2748 // for debugging purposes, these are useful to call to inspect the instruction
2807 void dump();2749 void dump();
...@@ -2846,8 +2788,8 @@ struct IrInstSrcCondBr {...@@ -2846,8 +2788,8 @@ struct IrInstSrcCondBr {
2846 IrInstSrc base;2788 IrInstSrc base;
28472789
2848 IrInstSrc *condition;2790 IrInstSrc *condition;
2849 IrBasicBlockSrc *then_block;2791 Stage1ZirBasicBlock *then_block;
2850 IrBasicBlockSrc *else_block;2792 Stage1ZirBasicBlock *else_block;
2851 IrInstSrc *is_comptime;2793 IrInstSrc *is_comptime;
2852 ResultLoc *result_loc;2794 ResultLoc *result_loc;
2853};2795};
...@@ -2863,7 +2805,7 @@ struct IrInstGenCondBr {...@@ -2863,7 +2805,7 @@ struct IrInstGenCondBr {
2863struct IrInstSrcBr {2805struct IrInstSrcBr {
2864 IrInstSrc base;2806 IrInstSrc base;
28652807
2866 IrBasicBlockSrc *dest_block;2808 Stage1ZirBasicBlock *dest_block;
2867 IrInstSrc *is_comptime;2809 IrInstSrc *is_comptime;
2868};2810};
28692811
...@@ -2875,14 +2817,14 @@ struct IrInstGenBr {...@@ -2875,14 +2817,14 @@ struct IrInstGenBr {
28752817
2876struct IrInstSrcSwitchBrCase {2818struct IrInstSrcSwitchBrCase {
2877 IrInstSrc *value;2819 IrInstSrc *value;
2878 IrBasicBlockSrc *block;2820 Stage1ZirBasicBlock *block;
2879};2821};
28802822
2881struct IrInstSrcSwitchBr {2823struct IrInstSrcSwitchBr {
2882 IrInstSrc base;2824 IrInstSrc base;
28832825
2884 IrInstSrc *target_value;2826 IrInstSrc *target_value;
2885 IrBasicBlockSrc *else_block;2827 Stage1ZirBasicBlock *else_block;
2886 size_t case_count;2828 size_t case_count;
2887 IrInstSrcSwitchBrCase *cases;2829 IrInstSrcSwitchBrCase *cases;
2888 IrInstSrc *is_comptime;2830 IrInstSrc *is_comptime;
...@@ -2928,7 +2870,7 @@ struct IrInstSrcPhi {...@@ -2928,7 +2870,7 @@ struct IrInstSrcPhi {
2928 IrInstSrc base;2870 IrInstSrc base;
29292871
2930 size_t incoming_count;2872 size_t incoming_count;
2931 IrBasicBlockSrc **incoming_blocks;2873 Stage1ZirBasicBlock **incoming_blocks;
2932 IrInstSrc **incoming_values;2874 IrInstSrc **incoming_values;
2933 ResultLocPeerParent *peer_parent;2875 ResultLocPeerParent *peer_parent;
2934};2876};
...@@ -4592,7 +4534,7 @@ struct ResultLocPeerParent {...@@ -4592,7 +4534,7 @@ struct ResultLocPeerParent {
45924534
4593 bool skipped;4535 bool skipped;
4594 bool done_resuming;4536 bool done_resuming;
4595 IrBasicBlockSrc *end_bb;4537 Stage1ZirBasicBlock *end_bb;
4596 ResultLoc *parent;4538 ResultLoc *parent;
4597 ZigList<ResultLocPeer *> peers;4539 ZigList<ResultLocPeer *> peers;
4598 ZigType *resolved_type;4540 ZigType *resolved_type;
...@@ -4603,7 +4545,7 @@ struct ResultLocPeer {...@@ -4603,7 +4545,7 @@ struct ResultLocPeer {
4603 ResultLoc base;4545 ResultLoc base;
46044546
4605 ResultLocPeerParent *parent;4547 ResultLocPeerParent *parent;
4606 IrBasicBlockSrc *next_bb;4548 Stage1ZirBasicBlock *next_bb;
4607 IrSuspendPosition suspend_pos;4549 IrSuspendPosition suspend_pos;
4608};4550};
46094551
src/stage1/analyze.cpp+97-91
...@@ -6,9 +6,9 @@...@@ -6,9 +6,9 @@
6 */6 */
77
8#include "analyze.hpp"8#include "analyze.hpp"
9#include "ast_render.hpp"
10#include "codegen.hpp"9#include "codegen.hpp"
11#include "error.hpp"10#include "error.hpp"
11#include "astgen.hpp"
12#include "ir.hpp"12#include "ir.hpp"
13#include "ir_print.hpp"13#include "ir_print.hpp"
14#include "os.hpp"14#include "os.hpp"
...@@ -41,41 +41,44 @@ static bool is_top_level_struct(ZigType *import) {...@@ -41,41 +41,44 @@ static bool is_top_level_struct(ZigType *import) {
41 return import->id == ZigTypeIdStruct && import->data.structure.root_struct != nullptr;41 return import->id == ZigTypeIdStruct && import->data.structure.root_struct != nullptr;
42}42}
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{
45 assert(is_top_level_struct(owner));47 assert(is_top_level_struct(owner));
46 RootStruct *root_struct = owner->data.structure.root_struct;48 RootStruct *root_struct = owner->data.structure.root_struct;
4749 uint32_t byte_offset = root_struct->token_locs[token].offset;
48 ErrorMsg *err = err_msg_create_with_line(root_struct->path, token->start_line, token->start_column,50 ErrorMsg *err = err_msg_create_with_offset(root_struct->path, byte_offset,
49 root_struct->source_code, root_struct->line_offsets, msg);51 buf_ptr(root_struct->source_code), msg);
5052
51 err_msg_add_note(parent_msg, err);53 err_msg_add_note(parent_msg, err);
52 return err;54 return err;
53}55}
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{
56 assert(is_top_level_struct(owner));60 assert(is_top_level_struct(owner));
57 RootStruct *root_struct = owner->data.structure.root_struct;61 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,62 uint32_t byte_offset = root_struct->token_locs[token].offset + bad_index;
59 root_struct->source_code, root_struct->line_offsets, msg);63 ErrorMsg *err = err_msg_create_with_offset(root_struct->path, byte_offset,
64 buf_ptr(root_struct->source_code), msg);
6065
61 g->errors.append(err);66 g->errors.append(err);
62 g->trace_err = err;67 g->trace_err = err;
63 return err;68 return err;
64}69}
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
66ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) {75ErrorMsg *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;
70 node->already_traced_this_node = true;76 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);
72}78}
7379
74ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, const AstNode *node, Buf *msg) {80ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, const AstNode *node, Buf *msg) {
75 Token fake_token;81 return add_error_note_token(g, parent_msg, node->owner, node->main_token, msg);
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);
79}82}
8083
81ZigType *new_type_table_entry(ZigTypeId id) {84ZigType *new_type_table_entry(ZigTypeId id) {
...@@ -913,13 +916,27 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) {...@@ -913,13 +916,27 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) {
913 return entry;916 return entry;
914}917}
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{
917 ZigType *entry = new_type_table_entry(ZigTypeIdOpaque);934 ZigType *entry = new_type_table_entry(ZigTypeIdOpaque);
918935
919 buf_init_from_str(&entry->name, full_name);936 buf_init_from_str(&entry->name, full_name);
920937
921 ZigType *import = scope ? get_scope_import(scope) : nullptr;938 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
924 // Note: duplicated in get_partial_container_type941 // Note: duplicated in get_partial_container_type
925 entry->llvm_type = LLVMInt8Type();942 entry->llvm_type = LLVMInt8Type();
...@@ -1142,7 +1159,7 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind...@@ -1142,7 +1159,7 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind
1142 break;1159 break;
1143 case ContainerKindOpaque: {1160 case ContainerKindOpaque: {
1144 ZigType *import = scope ? get_scope_import(scope) : nullptr;1161 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;
1146 // Note: duplicated in get_opaque_type1163 // Note: duplicated in get_opaque_type
1147 entry->llvm_type = LLVMInt8Type();1164 entry->llvm_type = LLVMInt8Type();
1148 entry->llvm_di_type = ZigLLVMCreateDebugForwardDeclType(g->dbuilder,1165 entry->llvm_di_type = ZigLLVMCreateDebugForwardDeclType(g->dbuilder,
...@@ -1584,8 +1601,9 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ZigV...@@ -1584,8 +1601,9 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ZigV
1584ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {1601ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {
1585 Error err;1602 Error err;
1586 // Hot path for simple identifiers, to avoid unnecessary memory allocations.1603 // Hot path for simple identifiers, to avoid unnecessary memory allocations.
1587 if (node->type == NodeTypeSymbol) {1604 if (node->type == NodeTypeIdentifier) {
1588 Buf *variable_name = node->data.symbol_expr.symbol;1605 RootStruct *root_struct = node->owner->data.structure.root_struct;
1606 Buf *variable_name = token_identifier_buf(root_struct, node->main_token);
1589 if (buf_eql_str(variable_name, "_"))1607 if (buf_eql_str(variable_name, "_"))
1590 goto abort_hot_path;1608 goto abort_hot_path;
1591 ZigType *primitive_type;1609 ZigType *primitive_type;
...@@ -2034,7 +2052,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc...@@ -2034,7 +2052,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
2034 buf_sprintf("var args only allowed in functions with C calling convention"));2052 buf_sprintf("var args only allowed in functions with C calling convention"));
2035 return g->builtin_types.entry_invalid;2053 return g->builtin_types.entry_invalid;
2036 }2054 }
2037 } else if (param_node->data.param_decl.anytype_token != nullptr) {2055 } else if (param_node->data.param_decl.anytype_token != 0) {
2038 if (!calling_convention_allows_zig_types(fn_type_id.cc)) {2056 if (!calling_convention_allows_zig_types(fn_type_id.cc)) {
2039 add_node_error(g, param_node,2057 add_node_error(g, param_node,
2040 buf_sprintf("parameter of type 'anytype' not allowed in function with calling convention '%s'",2058 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) {...@@ -3021,7 +3039,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
3021 field_node = decl_node->data.container_decl.fields.at(i);3039 field_node = decl_node->data.container_decl.fields.at(i);
3022 type_struct_field->name = field_node->data.struct_field.name;3040 type_struct_field->name = field_node->data.struct_field.name;
3023 type_struct_field->decl_node = field_node;3041 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) {
3025 if (field_node->data.struct_field.value == nullptr) {3043 if (field_node->data.struct_field.value == nullptr) {
3026 add_token_error(g, field_node->owner,3044 add_token_error(g, field_node->owner,
3027 field_node->data.struct_field.comptime_token,3045 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...@@ -3635,14 +3653,7 @@ static void get_fully_qualified_decl_name(CodeGen *g, Buf *buf, Tld *tld, bool i
36353653
3636static ZigFn *create_fn_raw(CodeGen *g, bool is_noinline) {3654static ZigFn *create_fn_raw(CodeGen *g, bool is_noinline) {
3637 ZigFn *fn_entry = heap::c_allocator.create<ZigFn>();3655 ZigFn *fn_entry = heap::c_allocator.create<ZigFn>();
3638 fn_entry->ir_executable = heap::c_allocator.create<IrExecutableSrc>();3656 fn_entry->stage1_zir = heap::c_allocator.create<Stage1Zir>();
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;
3646 fn_entry->is_noinline = is_noinline;3657 fn_entry->is_noinline = is_noinline;
36473658
3648 return fn_entry;3659 return fn_entry;
...@@ -4042,7 +4053,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {...@@ -4042,7 +4053,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
4042 case NodeTypeBoolLiteral:4053 case NodeTypeBoolLiteral:
4043 case NodeTypeNullLiteral:4054 case NodeTypeNullLiteral:
4044 case NodeTypeUndefinedLiteral:4055 case NodeTypeUndefinedLiteral:
4045 case NodeTypeSymbol:4056 case NodeTypeIdentifier:
4046 case NodeTypePrefixOpExpr:4057 case NodeTypePrefixOpExpr:
4047 case NodeTypePointerType:4058 case NodeTypePointerType:
4048 case NodeTypeIfBoolExpr:4059 case NodeTypeIfBoolExpr:
...@@ -4238,7 +4249,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) {...@@ -4238,7 +4249,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) {
4238 bool is_const = var_decl->is_const;4249 bool is_const = var_decl->is_const;
4239 bool is_extern = var_decl->is_extern;4250 bool is_extern = var_decl->is_extern;
4240 bool is_export = var_decl->is_export;4251 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
4243 ZigType *explicit_type = nullptr;4254 ZigType *explicit_type = nullptr;
4244 if (var_decl->type) {4255 if (var_decl->type) {
...@@ -5116,8 +5127,11 @@ static void analyze_fn_ir(CodeGen *g, ZigFn *fn, AstNode *return_type_node) {...@@ -5116,8 +5127,11 @@ static void analyze_fn_ir(CodeGen *g, ZigFn *fn, AstNode *return_type_node) {
5116 if (fn->analyzed_executable.source_node == nullptr) {5127 if (fn->analyzed_executable.source_node == nullptr) {
5117 fn->analyzed_executable.source_node = fn->body_node;5128 fn->analyzed_executable.source_node = fn->body_node;
5118 }5129 }
5119 ZigType *block_return_type = ir_analyze(g, fn->ir_executable,5130 size_t backward_branch_count = 0;
5120 &fn->analyzed_executable, fn_type_id->return_type, return_type_node, nullptr);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);
5121 fn->src_implicit_return_type = block_return_type;5135 fn->src_implicit_return_type = block_return_type;
51225136
5123 if (type_is_invalid(block_return_type) || fn->analyzed_executable.first_err_trace_msg != nullptr) {5137 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) {...@@ -5214,21 +5228,19 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
5214 ZigType *fn_type = fn_table_entry->type_entry;5228 ZigType *fn_type = fn_table_entry->type_entry;
5215 assert(!fn_type->data.fn.is_generic);5229 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)) {
5218 fn_table_entry->anal_state = FnAnalStateInvalid;5232 fn_table_entry->anal_state = FnAnalStateInvalid;
5219 return;5233 return;
5220 }5234 }
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) {
5223 fn_table_entry->anal_state = FnAnalStateInvalid;5237 fn_table_entry->anal_state = FnAnalStateInvalid;
5224 return;5238 return;
5225 }5239 }
52265240
5227 if (g->verbose_ir) {5241 if (g->verbose_ir) {
5228 fprintf(stderr, "\n");
5229 ast_render(stderr, fn_table_entry->body_node, 4);
5230 fprintf(stderr, "\nfn %s() { // (IR)\n", buf_ptr(&fn_table_entry->symbol_name));5242 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);
5232 fprintf(stderr, "}\n");5244 fprintf(stderr, "}\n");
5233 }5245 }
52345246
...@@ -5238,33 +5250,17 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {...@@ -5238,33 +5250,17 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
5238ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Buf *source_code,5250ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Buf *source_code,
5239 SourceKind source_kind)5251 SourceKind source_kind)
5240{5252{
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
5250 Tokenization tokenization = {0};5253 Tokenization tokenization = {0};
5251 tokenize(source_code, &tokenization);5254 tokenize(buf_ptr(source_code), &tokenization);
52525255
5253 if (tokenization.err) {5256 if (tokenization.err) {
5254 ErrorMsg *err = err_msg_create_with_line(resolved_path, tokenization.err_line, tokenization.err_column,5257 ErrorMsg *err = err_msg_create_with_offset(resolved_path, tokenization.err_byte_offset,
5255 source_code, tokenization.line_offsets, tokenization.err);5258 buf_ptr(source_code), tokenization.err);
52565259
5257 print_err_msg(err, g->err_color);5260 print_err_msg(err, g->err_color);
5258 exit(1);5261 exit(1);
5259 }5262 }
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
5268 Buf *src_dirname = buf_alloc();5264 Buf *src_dirname = buf_alloc();
5269 Buf *src_basename = buf_alloc();5265 Buf *src_basename = buf_alloc();
5270 os_path_split(resolved_path, src_dirname, src_basename);5266 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...@@ -5297,9 +5293,20 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu
5297 RootStruct *root_struct = heap::c_allocator.create<RootStruct>();5293 RootStruct *root_struct = heap::c_allocator.create<RootStruct>();
5298 root_struct->package = package;5294 root_struct->package = package;
5299 root_struct->source_code = source_code;5295 root_struct->source_code = source_code;
5300 root_struct->line_offsets = tokenization.line_offsets;
5301 root_struct->path = resolved_path;5296 root_struct->path = resolved_path;
5302 root_struct->di_file = ZigLLVMCreateFile(g->dbuilder, buf_ptr(src_basename), buf_ptr(src_dirname));5297 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
5303 ZigType *import_entry = get_root_container_type(g, buf_ptr(namespace_name), bare_name, root_struct);5310 ZigType *import_entry = get_root_container_type(g, buf_ptr(namespace_name), bare_name, root_struct);
5304 if (source_kind == SourceKindRoot) {5311 if (source_kind == SourceKindRoot) {
5305 assert(g->root_import == nullptr);5312 assert(g->root_import == nullptr);
...@@ -5307,14 +5314,11 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu...@@ -5307,14 +5314,11 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu
5307 }5314 }
5308 g->import_table.put(resolved_path, import_entry);5315 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);
5311 assert(root_node != nullptr);5318 assert(root_node != nullptr);
5312 assert(root_node->type == NodeTypeContainerDecl);5319 assert(root_node->type == NodeTypeContainerDecl);
5313 import_entry->data.structure.decl_node = root_node;5320 import_entry->data.structure.decl_node = root_node;
5314 import_entry->data.structure.decls_scope->base.source_node = root_node;5321 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
5319 for (size_t decl_i = 0; decl_i < root_node->data.container_decl.decls.length; decl_i += 1) {5323 for (size_t decl_i = 0; decl_i < root_node->data.container_decl.decls.length; decl_i += 1) {
5320 AstNode *top_level_decl = root_node->data.container_decl.decls.at(decl_i);5324 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) {...@@ -6254,9 +6258,12 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *ty) {
6254 zig_unreachable();6258 zig_unreachable();
6255}6259}
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) {
6258 auto entry = g->string_literals_table.maybe_get(str);6262 auto entry = g->string_literals_table.maybe_get(str);
6259 if (entry != nullptr) {6263 if (entry != nullptr) {
6264 if (move_str) {
6265 buf_destroy(str);
6266 }
6260 memcpy(const_val, entry->value, sizeof(ZigValue));6267 memcpy(const_val, entry->value, sizeof(ZigValue));
6261 return;6268 return;
6262 }6269 }
...@@ -6280,7 +6287,7 @@ void init_const_str_lit(CodeGen *g, ZigValue *const_val, Buf *str) {...@@ -6280,7 +6287,7 @@ void init_const_str_lit(CodeGen *g, ZigValue *const_val, Buf *str) {
62806287
6281ZigValue *create_const_str_lit(CodeGen *g, Buf *str) {6288ZigValue *create_const_str_lit(CodeGen *g, Buf *str) {
6282 ZigValue *const_val = g->pass1_arena->create<ZigValue>();6289 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);
6284 return const_val;6291 return const_val;
6285}6292}
62866293
...@@ -8626,7 +8633,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -8626,7 +8633,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
8626 ZigType *import = get_scope_import(scope);8633 ZigType *import = get_scope_import(scope);
8627 di_file = import->data.structure.root_struct->di_file;8634 di_file = import->data.structure.root_struct->di_file;
8628 di_scope = ZigLLVMFileToScope(di_file);8635 di_scope = ZigLLVMFileToScope(di_file);
8629 line = decl_node->line + 1;8636 line = node_line_onebased(decl_node);
8630 } else {8637 } else {
8631 di_file = nullptr;8638 di_file = nullptr;
8632 di_scope = ZigLLVMCompileUnitToScope(g->compile_unit);8639 di_scope = ZigLLVMCompileUnitToScope(g->compile_unit);
...@@ -8830,7 +8837,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -8830,7 +8837,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
8830 unsigned line;8837 unsigned line;
8831 if (decl_node != nullptr) {8838 if (decl_node != nullptr) {
8832 AstNode *field_node = field->decl_node;8839 AstNode *field_node = field->decl_node;
8833 line = field_node->line + 1;8840 line = node_line_onebased(field_node);
8834 } else {8841 } else {
8835 line = 0;8842 line = 0;
8836 }8843 }
...@@ -8881,7 +8888,7 @@ static ZigLLVMDIType *make_empty_namespace_llvm_di_type(CodeGen *g, ZigType *imp...@@ -8881,7 +8888,7 @@ static ZigLLVMDIType *make_empty_namespace_llvm_di_type(CodeGen *g, ZigType *imp
8881 return ZigLLVMCreateDebugStructType(g->dbuilder,8888 return ZigLLVMCreateDebugStructType(g->dbuilder,
8882 ZigLLVMFileToScope(import->data.structure.root_struct->di_file),8889 ZigLLVMFileToScope(import->data.structure.root_struct->di_file),
8883 name,8890 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),
8885 debug_size_in_bits,8892 debug_size_in_bits,
8886 debug_align_in_bits,8893 debug_align_in_bits,
8887 ZigLLVM_DIFlags_Zero,8894 ZigLLVM_DIFlags_Zero,
...@@ -8926,7 +8933,7 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type, ResolveStatu...@@ -8926,7 +8933,7 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type, ResolveStatu
8926 uint64_t tag_debug_align_in_bits = 8*tag_int_type->abi_align;8933 uint64_t tag_debug_align_in_bits = 8*tag_int_type->abi_align;
8927 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,8934 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
8928 ZigLLVMFileToScope(import->data.structure.root_struct->di_file), buf_ptr(&enum_type->name),8935 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),
8930 tag_debug_size_in_bits,8937 tag_debug_size_in_bits,
8931 tag_debug_align_in_bits,8938 tag_debug_align_in_bits,
8932 di_enumerators, field_count,8939 di_enumerators, field_count,
...@@ -8966,12 +8973,12 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta...@@ -8966,12 +8973,12 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
89668973
8967 if (union_type->data.unionation.resolve_status < ResolveStatusLLVMFwdDecl) {8974 if (union_type->data.unionation.resolve_status < ResolveStatusLLVMFwdDecl) {
8968 union_type->llvm_type = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&union_type->name));8975 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;
8970 unsigned dwarf_kind = ZigLLVMTag_DW_structure_type();8977 unsigned dwarf_kind = ZigLLVMTag_DW_structure_type();
8971 union_type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,8978 union_type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
8972 dwarf_kind, buf_ptr(&union_type->name),8979 dwarf_kind, buf_ptr(&union_type->name),
8973 ZigLLVMFileToScope(import->data.structure.root_struct->di_file),8980 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
8976 union_type->data.unionation.resolve_status = ResolveStatusLLVMFwdDecl;8983 union_type->data.unionation.resolve_status = ResolveStatusLLVMFwdDecl;
8977 if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return;8984 if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return;
...@@ -8992,7 +8999,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta...@@ -8992,7 +8999,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
8992 AstNode *field_node = union_field->decl_node;8999 AstNode *field_node = union_field->decl_node;
8993 union_inner_di_types[union_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,9000 union_inner_di_types[union_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
8994 ZigLLVMTypeToScope(union_type->llvm_di_type), buf_ptr(union_field->enum_field->name),9001 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),
8996 store_size_in_bits,9003 store_size_in_bits,
8997 abi_align_in_bits,9004 abi_align_in_bits,
8998 0,9005 0,
...@@ -9022,7 +9029,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta...@@ -9022,7 +9029,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
9022 // create debug type for union9029 // create debug type for union
9023 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder,9030 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder,
9024 ZigLLVMFileToScope(import->data.structure.root_struct->di_file), buf_ptr(&union_type->name),9031 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),
9026 union_type->data.unionation.union_abi_size * 8,9033 union_type->data.unionation.union_abi_size * 8,
9027 most_aligned_union_member->align * 8,9034 most_aligned_union_member->align * 8,
9028 ZigLLVM_DIFlags_Zero, union_inner_di_types,9035 ZigLLVM_DIFlags_Zero, union_inner_di_types,
...@@ -9057,7 +9064,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta...@@ -9057,7 +9064,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
9057 // create debug type for union9064 // create debug type for union
9058 ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder,9065 ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder,
9059 ZigLLVMTypeToScope(union_type->llvm_di_type), "AnonUnion",9066 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),
9061 most_aligned_union_member->type_entry->size_in_bits, 8*most_aligned_union_member->align,9068 most_aligned_union_member->type_entry->size_in_bits, 8*most_aligned_union_member->align,
9062 ZigLLVM_DIFlags_Zero, union_inner_di_types, gen_field_count, 0, "");9069 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...@@ -9068,7 +9075,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
90689075
9069 ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,9076 ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,
9070 ZigLLVMTypeToScope(union_type->llvm_di_type), "payload",9077 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),
9072 most_aligned_union_member->type_entry->size_in_bits,9079 most_aligned_union_member->type_entry->size_in_bits,
9073 8*most_aligned_union_member->align,9080 8*most_aligned_union_member->align,
9074 union_offset_in_bits,9081 union_offset_in_bits,
...@@ -9079,7 +9086,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta...@@ -9079,7 +9086,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
90799086
9080 ZigLLVMDIType *tag_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,9087 ZigLLVMDIType *tag_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,
9081 ZigLLVMTypeToScope(union_type->llvm_di_type), "tag",9088 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),
9083 tag_debug_size_in_bits,9090 tag_debug_size_in_bits,
9084 tag_debug_align_in_bits,9091 tag_debug_align_in_bits,
9085 tag_offset_in_bits,9092 tag_offset_in_bits,
...@@ -9094,7 +9101,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta...@@ -9094,7 +9101,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
9094 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,9101 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
9095 ZigLLVMFileToScope(import->data.structure.root_struct->di_file),9102 ZigLLVMFileToScope(import->data.structure.root_struct->di_file),
9096 buf_ptr(&union_type->name),9103 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),
9098 debug_size_in_bits,9105 debug_size_in_bits,
9099 debug_align_in_bits,9106 debug_align_in_bits,
9100 ZigLLVM_DIFlags_Zero, nullptr, di_root_members, 2, 0, nullptr, "");9107 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...@@ -9774,9 +9781,9 @@ void src_assert_impl(bool ok, AstNode *source_node, char const *file, unsigned i
9774 if (source_node == nullptr) {9781 if (source_node == nullptr) {
9775 fprintf(stderr, "when analyzing (unknown source location) ");9782 fprintf(stderr, "when analyzing (unknown source location) ");
9776 } else {9783 } else {
9777 fprintf(stderr, "when analyzing %s:%u:%u ",9784 RootStruct *root_struct = source_node->owner->data.structure.root_struct;
9778 buf_ptr(source_node->owner->data.structure.root_struct->path),9785 fprintf(stderr, "when analyzing %s:%u:%u ", buf_ptr(root_struct->path),
9779 (unsigned)source_node->line + 1, (unsigned)source_node->column + 1);9786 node_line_onebased(source_node), node_column_onebased(source_node));
9780 }9787 }
9781 fprintf(stderr, "in compiler source at %s:%u: ", file, line);9788 fprintf(stderr, "in compiler source at %s:%u: ", file, line);
9782 const char *msg = "assertion failed. This is a bug in the Zig compiler.";9789 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,...@@ -9842,18 +9849,17 @@ Error analyze_import(CodeGen *g, ZigType *source_import, Buf *import_target_str,
9842 return ErrorNone;9849 return ErrorNone;
9843}9850}
98449851
98459852void AstNode::src() {
9846void IrExecutableSrc::src() {9853 RootStruct *root_struct = this->owner->data.structure.root_struct;
9847 if (this->source_node != nullptr) {9854 uint32_t line = root_struct->token_locs[this->main_token].line + 1;
9848 this->source_node->src();9855 uint32_t column = root_struct->token_locs[this->main_token].column + 1;
9849 }9856 fprintf(stderr, "%s:%" PRIu32 ":%" PRIu32 "\n",
9850 if (this->parent_exec != nullptr) {9857 buf_ptr(root_struct->path),
9851 this->parent_exec->src();9858 line, column);
9852 }
9853}9859}
98549860
9855void IrExecutableGen::src() {9861void Stage1Air::src() {
9856 IrExecutableGen *it;9862 Stage1Air *it;
9857 for (it = this; it != nullptr && it->source_node != nullptr; it = it->parent_exec) {9863 for (it = this; it != nullptr && it->source_node != nullptr; it = it->parent_exec) {
9858 it->source_node->src();9864 it->source_node->src();
9859 }9865 }
src/stage1/analyze.hpp+4-2
...@@ -12,7 +12,9 @@...@@ -12,7 +12,9 @@
1212
13void semantic_analyze(CodeGen *g);13void semantic_analyze(CodeGen *g);
14ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg);14ErrorMsg *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);
16ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, const AstNode *node, Buf *msg);18ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, const AstNode *node, Buf *msg);
17ZigType *new_type_table_entry(ZigTypeId id);19ZigType *new_type_table_entry(ZigTypeId id);
18ZigType *get_fn_frame_type(CodeGen *g, ZigFn *fn);20ZigType *get_fn_frame_type(CodeGen *g, ZigFn *fn);
...@@ -140,7 +142,7 @@ Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstSrc...@@ -140,7 +142,7 @@ Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstSrc
140Scope *create_typeof_scope(CodeGen *g, AstNode *node, Scope *parent);142Scope *create_typeof_scope(CodeGen *g, AstNode *node, Scope *parent);
141ScopeExpr *create_expr_scope(CodeGen *g, AstNode *node, Scope *parent);143ScopeExpr *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);
144ZigValue *create_const_str_lit(CodeGen *g, Buf *str);146ZigValue *create_const_str_lit(CodeGen *g, Buf *str);
145147
146void init_const_bigint(ZigValue *const_val, ZigType *type, const BigInt *bigint);148void 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) {...@@ -69,7 +69,7 @@ void bigfloat_init_bigint(BigFloat *dest, const BigInt *op) {
69 }69 }
70}70}
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) {
73 char *str_begin = (char *)buf_ptr;73 char *str_begin = (char *)buf_ptr;
74 char *str_end;74 char *str_end;
7575
...@@ -79,7 +79,6 @@ Error bigfloat_init_buf(BigFloat *dest, const uint8_t *buf_ptr, size_t buf_len)...@@ -79,7 +79,6 @@ Error bigfloat_init_buf(BigFloat *dest, const uint8_t *buf_ptr, size_t buf_len)
79 return ErrorOverflow;79 return ErrorOverflow;
80 }80 }
8181
82 assert(str_end <= ((char*)buf_ptr) + buf_len);
83 return ErrorNone;82 return ErrorNone;
84}83}
8584
src/stage1/bigfloat.hpp+1-1
...@@ -28,7 +28,7 @@ void bigfloat_init_64(BigFloat *dest, double x);...@@ -28,7 +28,7 @@ void bigfloat_init_64(BigFloat *dest, double x);
28void bigfloat_init_128(BigFloat *dest, float128_t x);28void bigfloat_init_128(BigFloat *dest, float128_t x);
29void bigfloat_init_bigfloat(BigFloat *dest, const BigFloat *x);29void bigfloat_init_bigfloat(BigFloat *dest, const BigFloat *x);
30void bigfloat_init_bigint(BigFloat *dest, const BigInt *op);30void 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
33float16_t bigfloat_to_f16(const BigFloat *bigfloat);33float16_t bigfloat_to_f16(const BigFloat *bigfloat);
34float bigfloat_to_f32(const BigFloat *bigfloat);34float bigfloat_to_f32(const BigFloat *bigfloat);
src/stage1/codegen.cpp+119-107
...@@ -6,7 +6,6 @@...@@ -6,7 +6,6 @@
6 */6 */
77
8#include "analyze.hpp"8#include "analyze.hpp"
9#include "ast_render.hpp"
10#include "codegen.hpp"9#include "codegen.hpp"
11#include "errmsg.hpp"10#include "errmsg.hpp"
12#include "error.hpp"11#include "error.hpp"
...@@ -642,6 +641,18 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn) {...@@ -642,6 +641,18 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn) {
642 return fn->llvm_value;641 return fn->llvm_value;
643}642}
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
645static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {656static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
646 if (scope->di_scope)657 if (scope->di_scope)
647 return scope->di_scope;658 return scope->di_scope;
...@@ -657,8 +668,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {...@@ -657,8 +668,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
657 ZigFn *fn_table_entry = fn_scope->fn_entry;668 ZigFn *fn_table_entry = fn_scope->fn_entry;
658 if (!fn_table_entry->proto_node)669 if (!fn_table_entry->proto_node)
659 return get_di_scope(g, scope->parent);670 return get_di_scope(g, scope->parent);
660 unsigned line_number = (unsigned)(fn_table_entry->proto_node->line == 0) ?671 unsigned line_number = node_line_onebased(fn_table_entry->proto_node);
661 0 : (fn_table_entry->proto_node->line + 1);
662 unsigned scope_line = line_number;672 unsigned scope_line = line_number;
663 bool is_definition = fn_table_entry->body_node != nullptr;673 bool is_definition = fn_table_entry->body_node != nullptr;
664 bool is_optimized = g->build_mode != BuildModeDebug;674 bool is_optimized = g->build_mode != BuildModeDebug;
...@@ -696,8 +706,8 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {...@@ -696,8 +706,8 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
696 ZigLLVMDILexicalBlock *di_block = ZigLLVMCreateLexicalBlock(g->dbuilder,706 ZigLLVMDILexicalBlock *di_block = ZigLLVMCreateLexicalBlock(g->dbuilder,
697 get_di_scope(g, scope->parent),707 get_di_scope(g, scope->parent),
698 import->data.structure.root_struct->di_file,708 import->data.structure.root_struct->di_file,
699 (unsigned)scope->source_node->line + 1,709 node_line_onebased(scope->source_node),
700 (unsigned)scope->source_node->column + 1);710 node_column_onebased(scope->source_node));
701 scope->di_scope = ZigLLVMLexicalBlockToScope(di_block);711 scope->di_scope = ZigLLVMLexicalBlockToScope(di_block);
702 return scope->di_scope;712 return scope->di_scope;
703 }713 }
...@@ -1798,8 +1808,8 @@ static void gen_var_debug_decl(CodeGen *g, ZigVar *var) {...@@ -1798,8 +1808,8 @@ static void gen_var_debug_decl(CodeGen *g, ZigVar *var) {
1798 if (g->strip_debug_symbols) return;1808 if (g->strip_debug_symbols) return;
1799 assert(var->di_loc_var != nullptr);1809 assert(var->di_loc_var != nullptr);
1800 AstNode *source_node = var->decl_node;1810 AstNode *source_node = var->decl_node;
1801 ZigLLVMDILocation *debug_loc = ZigLLVMGetDebugLoc((unsigned)source_node->line + 1,1811 ZigLLVMDILocation *debug_loc = ZigLLVMGetDebugLoc(node_line_onebased(source_node),
1802 (unsigned)source_node->column + 1, get_di_scope(g, var->parent_scope));1812 node_column_onebased(source_node), get_di_scope(g, var->parent_scope));
1803 ZigLLVMInsertDeclareAtEnd(g->dbuilder, var->value_ref, var->di_loc_var, debug_loc,1813 ZigLLVMInsertDeclareAtEnd(g->dbuilder, var->value_ref, var->di_loc_var, debug_loc,
1804 LLVMGetInsertBlock(g->builder));1814 LLVMGetInsertBlock(g->builder));
1805}1815}
...@@ -2198,7 +2208,7 @@ var_ok:...@@ -2198,7 +2208,7 @@ var_ok:
2198 // arg index + 1 because the 0 index is return value2208 // arg index + 1 because the 0 index is return value
2199 var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope),2209 var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
2200 var->name, fn_walk->data.vars.import->data.structure.root_struct->di_file,2210 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),
2202 get_llvm_di_type(g, dest_ty), !g->strip_debug_symbols, 0, di_arg_index + 1);2212 get_llvm_di_type(g, dest_ty), !g->strip_debug_symbols, 0, di_arg_index + 1);
2203 }2213 }
2204 return true;2214 return true;
...@@ -2433,7 +2443,7 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {...@@ -2433,7 +2443,7 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
2433 return fn_val;2443 return fn_val;
24342444
2435}2445}
2436static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, IrExecutableGen *executable,2446static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, Stage1Air *executable,
2437 IrInstGenSaveErrRetAddr *save_err_ret_addr_instruction)2447 IrInstGenSaveErrRetAddr *save_err_ret_addr_instruction)
2438{2448{
2439 assert(g->have_err_ret_tracing);2449 assert(g->have_err_ret_tracing);
...@@ -2626,7 +2636,7 @@ static void gen_async_return(CodeGen *g, IrInstGenReturn *instruction) {...@@ -2626,7 +2636,7 @@ static void gen_async_return(CodeGen *g, IrInstGenReturn *instruction) {
2626 LLVMBuildRetVoid(g->builder);2636 LLVMBuildRetVoid(g->builder);
2627}2637}
26282638
2629static LLVMValueRef ir_render_return(CodeGen *g, IrExecutableGen *executable, IrInstGenReturn *instruction) {2639static LLVMValueRef ir_render_return(CodeGen *g, Stage1Air *executable, IrInstGenReturn *instruction) {
2630 if (fn_is_async(g->cur_fn)) {2640 if (fn_is_async(g->cur_fn)) {
2631 gen_async_return(g, instruction);2641 gen_async_return(g, instruction);
2632 return nullptr;2642 return nullptr;
...@@ -3051,7 +3061,7 @@ static void gen_shift_rhs_check(CodeGen *g, ZigType *lhs_type, ZigType *rhs_type...@@ -3051,7 +3061,7 @@ static void gen_shift_rhs_check(CodeGen *g, ZigType *lhs_type, ZigType *rhs_type
3051 }3061 }
3052}3062}
30533063
3054static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutableGen *executable,3064static LLVMValueRef ir_render_bin_op(CodeGen *g, Stage1Air *executable,
3055 IrInstGenBinOp *bin_op_instruction)3065 IrInstGenBinOp *bin_op_instruction)
3056{3066{
3057 IrBinOp op_id = bin_op_instruction->op_id;3067 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...@@ -3273,7 +3283,7 @@ static void add_error_range_check(CodeGen *g, ZigType *err_set_type, ZigType *in
3273 }3283 }
3274}3284}
32753285
3276static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutableGen *executable,3286static LLVMValueRef ir_render_cast(CodeGen *g, Stage1Air *executable,
3277 IrInstGenCast *cast_instruction)3287 IrInstGenCast *cast_instruction)
3278{3288{
3279 Error err;3289 Error err;
...@@ -3357,7 +3367,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutableGen *executable,...@@ -3357,7 +3367,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutableGen *executable,
3357 zig_unreachable();3367 zig_unreachable();
3358}3368}
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,
3361 IrInstGenPtrOfArrayToSlice *instruction)3371 IrInstGenPtrOfArrayToSlice *instruction)
3362{3372{
3363 ZigType *actual_type = instruction->operand->value->type;3373 ZigType *actual_type = instruction->operand->value->type;
...@@ -3394,7 +3404,7 @@ static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutableGen...@@ -3394,7 +3404,7 @@ static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutableGen
3394 return result_loc;3404 return result_loc;
3395}3405}
33963406
3397static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutableGen *executable,3407static LLVMValueRef ir_render_ptr_cast(CodeGen *g, Stage1Air *executable,
3398 IrInstGenPtrCast *instruction)3408 IrInstGenPtrCast *instruction)
3399{3409{
3400 ZigType *wanted_type = instruction->base.value->type;3410 ZigType *wanted_type = instruction->base.value->type;
...@@ -3420,7 +3430,7 @@ static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutableGen *executable,...@@ -3420,7 +3430,7 @@ static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutableGen *executable,
3420 return result_ptr;3430 return result_ptr;
3421}3431}
34223432
3423static LLVMValueRef ir_render_bit_cast(CodeGen *g, IrExecutableGen *executable,3433static LLVMValueRef ir_render_bit_cast(CodeGen *g, Stage1Air *executable,
3424 IrInstGenBitCast *instruction)3434 IrInstGenBitCast *instruction)
3425{3435{
3426 ZigType *wanted_type = instruction->base.value->type;3436 ZigType *wanted_type = instruction->base.value->type;
...@@ -3448,7 +3458,7 @@ static LLVMValueRef ir_render_bit_cast(CodeGen *g, IrExecutableGen *executable,...@@ -3448,7 +3458,7 @@ static LLVMValueRef ir_render_bit_cast(CodeGen *g, IrExecutableGen *executable,
3448 }3458 }
3449}3459}
34503460
3451static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutableGen *executable,3461static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, Stage1Air *executable,
3452 IrInstGenWidenOrShorten *instruction)3462 IrInstGenWidenOrShorten *instruction)
3453{3463{
3454 ZigType *actual_type = instruction->target->value->type;3464 ZigType *actual_type = instruction->target->value->type;
...@@ -3465,7 +3475,7 @@ static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutableGen *exec...@@ -3465,7 +3475,7 @@ static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutableGen *exec
3465 instruction->base.value->type, target_val);3475 instruction->base.value->type, target_val);
3466}3476}
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) {
3469 ZigType *wanted_type = instruction->base.value->type;3479 ZigType *wanted_type = instruction->base.value->type;
3470 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);3480 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
3471 const uint32_t align_bytes = get_ptr_align(g, wanted_type);3481 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...@@ -3503,13 +3513,13 @@ static LLVMValueRef ir_render_int_to_ptr(CodeGen *g, IrExecutableGen *executable
3503 return LLVMBuildIntToPtr(g->builder, target_val, get_llvm_type(g, wanted_type), "");3513 return LLVMBuildIntToPtr(g->builder, target_val, get_llvm_type(g, wanted_type), "");
3504}3514}
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) {
3507 ZigType *wanted_type = instruction->base.value->type;3517 ZigType *wanted_type = instruction->base.value->type;
3508 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);3518 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
3509 return LLVMBuildPtrToInt(g->builder, target_val, get_llvm_type(g, wanted_type), "");3519 return LLVMBuildPtrToInt(g->builder, target_val, get_llvm_type(g, wanted_type), "");
3510}3520}
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) {
3513 ZigType *wanted_type = instruction->base.value->type;3523 ZigType *wanted_type = instruction->base.value->type;
3514 assert(wanted_type->id == ZigTypeIdEnum);3524 assert(wanted_type->id == ZigTypeIdEnum);
3515 ZigType *tag_int_type = wanted_type->data.enumeration.tag_int_type;3525 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...@@ -3549,7 +3559,7 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutableGen *executabl
3549 return tag_int_value;3559 return tag_int_value;
3550}3560}
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) {
3553 ZigType *wanted_type = instruction->base.value->type;3563 ZigType *wanted_type = instruction->base.value->type;
3554 assert(wanted_type->id == ZigTypeIdErrorSet);3564 assert(wanted_type->id == ZigTypeIdErrorSet);
35553565
...@@ -3566,7 +3576,7 @@ static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutableGen *executable...@@ -3566,7 +3576,7 @@ static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutableGen *executable
3566 return gen_widen_or_shorten(g, false, actual_type, g->err_tag_type, target_val);3576 return gen_widen_or_shorten(g, false, actual_type, g->err_tag_type, target_val);
3567}3577}
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) {
3570 ZigType *wanted_type = instruction->base.value->type;3580 ZigType *wanted_type = instruction->base.value->type;
3571 assert(wanted_type->id == ZigTypeIdInt);3581 assert(wanted_type->id == ZigTypeIdInt);
3572 assert(!wanted_type->data.integral.is_signed);3582 assert(!wanted_type->data.integral.is_signed);
...@@ -3592,7 +3602,7 @@ static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutableGen *executable...@@ -3592,7 +3602,7 @@ static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutableGen *executable
3592 }3602 }
3593}3603}
35943604
3595static LLVMValueRef ir_render_unreachable(CodeGen *g, IrExecutableGen *executable,3605static LLVMValueRef ir_render_unreachable(CodeGen *g, Stage1Air *executable,
3596 IrInstGenUnreachable *unreachable_instruction)3606 IrInstGenUnreachable *unreachable_instruction)
3597{3607{
3598 if (ir_want_runtime_safety(g, &unreachable_instruction->base)) {3608 if (ir_want_runtime_safety(g, &unreachable_instruction->base)) {
...@@ -3603,7 +3613,7 @@ static LLVMValueRef ir_render_unreachable(CodeGen *g, IrExecutableGen *executabl...@@ -3603,7 +3613,7 @@ static LLVMValueRef ir_render_unreachable(CodeGen *g, IrExecutableGen *executabl
3603 return nullptr;3613 return nullptr;
3604}3614}
36053615
3606static LLVMValueRef ir_render_cond_br(CodeGen *g, IrExecutableGen *executable,3616static LLVMValueRef ir_render_cond_br(CodeGen *g, Stage1Air *executable,
3607 IrInstGenCondBr *cond_br_instruction)3617 IrInstGenCondBr *cond_br_instruction)
3608{3618{
3609 LLVMBuildCondBr(g->builder,3619 LLVMBuildCondBr(g->builder,
...@@ -3613,12 +3623,12 @@ static LLVMValueRef ir_render_cond_br(CodeGen *g, IrExecutableGen *executable,...@@ -3613,12 +3623,12 @@ static LLVMValueRef ir_render_cond_br(CodeGen *g, IrExecutableGen *executable,
3613 return nullptr;3623 return nullptr;
3614}3624}
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) {
3617 LLVMBuildBr(g->builder, br_instruction->dest_block->llvm_block);3627 LLVMBuildBr(g->builder, br_instruction->dest_block->llvm_block);
3618 return nullptr;3628 return nullptr;
3619}3629}
36203630
3621static LLVMValueRef ir_render_binary_not(CodeGen *g, IrExecutableGen *executable,3631static LLVMValueRef ir_render_binary_not(CodeGen *g, Stage1Air *executable,
3622 IrInstGenBinaryNot *inst)3632 IrInstGenBinaryNot *inst)
3623{3633{
3624 LLVMValueRef operand = ir_llvm_value(g, inst->operand);3634 LLVMValueRef operand = ir_llvm_value(g, inst->operand);
...@@ -3650,13 +3660,13 @@ static LLVMValueRef ir_gen_negation(CodeGen *g, IrInstGen *inst, IrInstGen *oper...@@ -3650,13 +3660,13 @@ static LLVMValueRef ir_gen_negation(CodeGen *g, IrInstGen *inst, IrInstGen *oper
3650 }3660 }
3651}3661}
36523662
3653static LLVMValueRef ir_render_negation(CodeGen *g, IrExecutableGen *executable,3663static LLVMValueRef ir_render_negation(CodeGen *g, Stage1Air *executable,
3654 IrInstGenNegation *inst)3664 IrInstGenNegation *inst)
3655{3665{
3656 return ir_gen_negation(g, &inst->base, inst->operand, inst->wrapping);3666 return ir_gen_negation(g, &inst->base, inst->operand, inst->wrapping);
3657}3667}
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) {
3660 LLVMValueRef value = ir_llvm_value(g, instruction->value);3670 LLVMValueRef value = ir_llvm_value(g, instruction->value);
3661 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(value));3671 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(value));
3662 return LLVMBuildICmp(g->builder, LLVMIntEQ, value, zero, "");3672 return LLVMBuildICmp(g->builder, LLVMIntEQ, value, zero, "");
...@@ -3670,14 +3680,14 @@ static void render_decl_var(CodeGen *g, ZigVar *var) {...@@ -3670,14 +3680,14 @@ static void render_decl_var(CodeGen *g, ZigVar *var) {
3670 gen_var_debug_decl(g, var);3680 gen_var_debug_decl(g, var);
3671}3681}
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) {
3674 instruction->var->ptr_instruction = instruction->var_ptr;3684 instruction->var->ptr_instruction = instruction->var_ptr;
3675 instruction->var->did_the_decl_codegen = true;3685 instruction->var->did_the_decl_codegen = true;
3676 render_decl_var(g, instruction->var);3686 render_decl_var(g, instruction->var);
3677 return nullptr;3687 return nullptr;
3678}3688}
36793689
3680static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutableGen *executable,3690static LLVMValueRef ir_render_load_ptr(CodeGen *g, Stage1Air *executable,
3681 IrInstGenLoadPtr *instruction)3691 IrInstGenLoadPtr *instruction)
3682{3692{
3683 ZigType *child_type = instruction->base.value->type;3693 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...@@ -3879,7 +3889,7 @@ static void gen_undef_init(CodeGen *g, ZigType *ptr_type, ZigType *value_type, L
3879 gen_assign_raw(g, ptr, ptr_type, zero);3889 gen_assign_raw(g, ptr, ptr_type, zero);
3880}3890}
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) {
3883 Error err;3893 Error err;
38843894
3885 ZigType *ptr_type = instruction->ptr->value->type;3895 ZigType *ptr_type = instruction->ptr->value->type;
...@@ -3911,7 +3921,7 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutableGen *executable,...@@ -3911,7 +3921,7 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutableGen *executable,
3911 return nullptr;3921 return nullptr;
3912}3922}
39133923
3914static LLVMValueRef ir_render_vector_store_elem(CodeGen *g, IrExecutableGen *executable,3924static LLVMValueRef ir_render_vector_store_elem(CodeGen *g, Stage1Air *executable,
3915 IrInstGenVectorStoreElem *instruction)3925 IrInstGenVectorStoreElem *instruction)
3916{3926{
3917 LLVMValueRef vector_ptr = ir_llvm_value(g, instruction->vector_ptr);3927 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...@@ -3924,7 +3934,7 @@ static LLVMValueRef ir_render_vector_store_elem(CodeGen *g, IrExecutableGen *exe
3924 return nullptr;3934 return nullptr;
3925}3935}
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) {
3928 Error err;3938 Error err;
39293939
3930 ZigType *ptr_type = instruction->base.value->type;3940 ZigType *ptr_type = instruction->base.value->type;
...@@ -3951,7 +3961,7 @@ static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutableGen *executable, I...@@ -3951,7 +3961,7 @@ static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutableGen *executable, I
3951 get_llvm_type(g, ptr_type), "");3961 get_llvm_type(g, ptr_type), "");
3952}3962}
39533963
3954static LLVMValueRef ir_render_return_ptr(CodeGen *g, IrExecutableGen *executable,3964static LLVMValueRef ir_render_return_ptr(CodeGen *g, Stage1Air *executable,
3955 IrInstGenReturnPtr *instruction)3965 IrInstGenReturnPtr *instruction)
3956{3966{
3957 if (!type_has_bits(g, instruction->base.value->type))3967 if (!type_has_bits(g, instruction->base.value->type))
...@@ -3960,7 +3970,7 @@ static LLVMValueRef ir_render_return_ptr(CodeGen *g, IrExecutableGen *executable...@@ -3960,7 +3970,7 @@ static LLVMValueRef ir_render_return_ptr(CodeGen *g, IrExecutableGen *executable
3960 return g->cur_ret_ptr;3970 return g->cur_ret_ptr;
3961}3971}
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) {
3964 LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->array_ptr);3974 LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->array_ptr);
3965 ZigType *array_ptr_type = instruction->array_ptr->value->type;3975 ZigType *array_ptr_type = instruction->array_ptr->value->type;
3966 assert(array_ptr_type->id == ZigTypeIdPointer);3976 assert(array_ptr_type->id == ZigTypeIdPointer);
...@@ -4126,7 +4136,7 @@ static void render_async_spills(CodeGen *g) {...@@ -4126,7 +4136,7 @@ static void render_async_spills(CodeGen *g) {
4126 if (var->decl_node) {4136 if (var->decl_node) {
4127 var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),4137 var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
4128 var->name, import->data.structure.root_struct->di_file,4138 var->name, import->data.structure.root_struct->di_file,
4129 (unsigned)(var->decl_node->line + 1),4139 node_line_onebased(var->decl_node),
4130 get_llvm_di_type(g, var->var_type), !g->strip_debug_symbols, 0);4140 get_llvm_di_type(g, var->var_type), !g->strip_debug_symbols, 0);
4131 gen_var_debug_decl(g, var);4141 gen_var_debug_decl(g, var);
4132 }4142 }
...@@ -4212,7 +4222,7 @@ static void gen_init_stack_trace(CodeGen *g, LLVMValueRef trace_field_ptr, LLVMV...@@ -4212,7 +4222,7 @@ static void gen_init_stack_trace(CodeGen *g, LLVMValueRef trace_field_ptr, LLVMV
4212 LLVMBuildStore(g->builder, LLVMConstInt(usize_type_ref, stack_trace_ptr_count, false), addrs_len_ptr);4222 LLVMBuildStore(g->builder, LLVMConstInt(usize_type_ref, stack_trace_ptr_count, false), addrs_len_ptr);
4213}4223}
42144224
4215static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrInstGenCall *instruction) {4225static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, IrInstGenCall *instruction) {
4216 Error err;4226 Error err;
42174227
4218 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;4228 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...@@ -4632,7 +4642,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
4632 }4642 }
4633}4643}
46344644
4635static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutableGen *executable,4645static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, Stage1Air *executable,
4636 IrInstGenStructFieldPtr *instruction)4646 IrInstGenStructFieldPtr *instruction)
4637{4647{
4638 Error err;4648 Error err;
...@@ -4683,7 +4693,7 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutableGen *exec...@@ -4683,7 +4693,7 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutableGen *exec
4683 return field_ptr_val;4693 return field_ptr_val;
4684}4694}
46854695
4686static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutableGen *executable,4696static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, Stage1Air *executable,
4687 IrInstGenUnionFieldPtr *instruction)4697 IrInstGenUnionFieldPtr *instruction)
4688{4698{
4689 if (instruction->base.value->special != ConstValSpecialRuntime)4699 if (instruction->base.value->special != ConstValSpecialRuntime)
...@@ -4783,7 +4793,7 @@ static size_t find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok, Buf *src_...@@ -4783,7 +4793,7 @@ static size_t find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok, Buf *src_
4783 return SIZE_MAX;4793 return SIZE_MAX;
4784}4794}
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) {
4787 AstNode *asm_node = instruction->base.base.source_node;4797 AstNode *asm_node = instruction->base.base.source_node;
4788 assert(asm_node->type == NodeTypeAsmExpr);4798 assert(asm_node->type == NodeTypeAsmExpr);
4789 AstNodeAsmExpr *asm_expr = &asm_node->data.asm_expr;4799 AstNodeAsmExpr *asm_expr = &asm_node->data.asm_expr;
...@@ -4960,13 +4970,13 @@ static LLVMValueRef gen_non_null_bit(CodeGen *g, ZigType *maybe_type, LLVMValueR...@@ -4960,13 +4970,13 @@ static LLVMValueRef gen_non_null_bit(CodeGen *g, ZigType *maybe_type, LLVMValueR
4960 return gen_load_untyped(g, maybe_field_ptr, 0, false, "");4970 return gen_load_untyped(g, maybe_field_ptr, 0, false, "");
4961}4971}
49624972
4963static LLVMValueRef ir_render_test_non_null(CodeGen *g, IrExecutableGen *executable,4973static LLVMValueRef ir_render_test_non_null(CodeGen *g, Stage1Air *executable,
4964 IrInstGenTestNonNull *instruction)4974 IrInstGenTestNonNull *instruction)
4965{4975{
4966 return gen_non_null_bit(g, instruction->value->value->type, ir_llvm_value(g, instruction->value));4976 return gen_non_null_bit(g, instruction->value->value->type, ir_llvm_value(g, instruction->value));
4967}4977}
49684978
4969static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, IrExecutableGen *executable,4979static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, Stage1Air *executable,
4970 IrInstGenOptionalUnwrapPtr *instruction)4980 IrInstGenOptionalUnwrapPtr *instruction)
4971{4981{
4972 if (instruction->base.value->special != ConstValSpecialRuntime)4982 if (instruction->base.value->special != ConstValSpecialRuntime)
...@@ -5073,7 +5083,7 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *expr_type, BuiltinFn...@@ -5073,7 +5083,7 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *expr_type, BuiltinFn
5073 return fn_val;5083 return fn_val;
5074}5084}
50755085
5076static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutableGen *executable, IrInstGenClz *instruction) {5086static LLVMValueRef ir_render_clz(CodeGen *g, Stage1Air *executable, IrInstGenClz *instruction) {
5077 ZigType *int_type = instruction->op->value->type;5087 ZigType *int_type = instruction->op->value->type;
5078 LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdClz);5088 LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdClz);
5079 LLVMValueRef operand = ir_llvm_value(g, instruction->op);5089 LLVMValueRef operand = ir_llvm_value(g, instruction->op);
...@@ -5085,7 +5095,7 @@ static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutableGen *executable, IrIns...@@ -5085,7 +5095,7 @@ static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutableGen *executable, IrIns
5085 return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int);5095 return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int);
5086}5096}
50875097
5088static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutableGen *executable, IrInstGenCtz *instruction) {5098static LLVMValueRef ir_render_ctz(CodeGen *g, Stage1Air *executable, IrInstGenCtz *instruction) {
5089 ZigType *int_type = instruction->op->value->type;5099 ZigType *int_type = instruction->op->value->type;
5090 LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdCtz);5100 LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdCtz);
5091 LLVMValueRef operand = ir_llvm_value(g, instruction->op);5101 LLVMValueRef operand = ir_llvm_value(g, instruction->op);
...@@ -5097,7 +5107,7 @@ static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutableGen *executable, IrIns...@@ -5097,7 +5107,7 @@ static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutableGen *executable, IrIns
5097 return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int);5107 return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int);
5098}5108}
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) {
5101 uint64_t len_a = instruction->a->value->type->data.vector.len;5111 uint64_t len_a = instruction->a->value->type->data.vector.len;
5102 uint64_t len_mask = instruction->mask->value->type->data.vector.len;5112 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...@@ -5127,7 +5137,7 @@ static LLVMValueRef ir_render_shuffle_vector(CodeGen *g, IrExecutableGen *execut
5127 llvm_mask_value, "");5137 llvm_mask_value, "");
5128}5138}
51295139
5130static LLVMValueRef ir_render_splat(CodeGen *g, IrExecutableGen *executable, IrInstGenSplat *instruction) {5140static LLVMValueRef ir_render_splat(CodeGen *g, Stage1Air *executable, IrInstGenSplat *instruction) {
5131 ZigType *result_type = instruction->base.value->type;5141 ZigType *result_type = instruction->base.value->type;
5132 ir_assert(result_type->id == ZigTypeIdVector, &instruction->base);5142 ir_assert(result_type->id == ZigTypeIdVector, &instruction->base);
5133 uint32_t len = result_type->data.vector.len;5143 uint32_t len = result_type->data.vector.len;
...@@ -5139,7 +5149,7 @@ static LLVMValueRef ir_render_splat(CodeGen *g, IrExecutableGen *executable, IrI...@@ -5139,7 +5149,7 @@ static LLVMValueRef ir_render_splat(CodeGen *g, IrExecutableGen *executable, IrI
5139 return LLVMBuildShuffleVector(g->builder, op_vector, undef_vector, LLVMConstNull(mask_llvm_type), "");5149 return LLVMBuildShuffleVector(g->builder, op_vector, undef_vector, LLVMConstNull(mask_llvm_type), "");
5140}5150}
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) {
5143 ZigType *int_type = instruction->op->value->type;5153 ZigType *int_type = instruction->op->value->type;
5144 LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdPopCount);5154 LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdPopCount);
5145 LLVMValueRef operand = ir_llvm_value(g, instruction->op);5155 LLVMValueRef operand = ir_llvm_value(g, instruction->op);
...@@ -5147,7 +5157,7 @@ static LLVMValueRef ir_render_pop_count(CodeGen *g, IrExecutableGen *executable,...@@ -5147,7 +5157,7 @@ static LLVMValueRef ir_render_pop_count(CodeGen *g, IrExecutableGen *executable,
5147 return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int);5157 return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int);
5148}5158}
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) {
5151 ZigType *target_type = instruction->target_value->value->type;5161 ZigType *target_type = instruction->target_value->value->type;
5152 LLVMBasicBlockRef else_block = instruction->else_block->llvm_block;5162 LLVMBasicBlockRef else_block = instruction->else_block->llvm_block;
51535163
...@@ -5175,7 +5185,7 @@ static LLVMValueRef ir_render_switch_br(CodeGen *g, IrExecutableGen *executable,...@@ -5175,7 +5185,7 @@ static LLVMValueRef ir_render_switch_br(CodeGen *g, IrExecutableGen *executable,
5175 return nullptr;5185 return nullptr;
5176}5186}
51775187
5178static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutableGen *executable, IrInstGenPhi *instruction) {5188static LLVMValueRef ir_render_phi(CodeGen *g, Stage1Air *executable, IrInstGenPhi *instruction) {
5179 if (!type_has_bits(g, instruction->base.value->type))5189 if (!type_has_bits(g, instruction->base.value->type))
5180 return nullptr;5190 return nullptr;
51815191
...@@ -5199,7 +5209,7 @@ static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutableGen *executable, IrIns...@@ -5199,7 +5209,7 @@ static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutableGen *executable, IrIns
5199 return phi;5209 return phi;
5200}5210}
52015211
5202static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutableGen *executable, IrInstGenRef *instruction) {5212static LLVMValueRef ir_render_ref(CodeGen *g, Stage1Air *executable, IrInstGenRef *instruction) {
5203 if (!type_has_bits(g, instruction->base.value->type)) {5213 if (!type_has_bits(g, instruction->base.value->type)) {
5204 return nullptr;5214 return nullptr;
5205 }5215 }
...@@ -5219,7 +5229,7 @@ static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutableGen *executable, IrIns...@@ -5219,7 +5229,7 @@ static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutableGen *executable, IrIns
5219 }5229 }
5220}5230}
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) {
5223 assert(g->generate_error_name_table);5233 assert(g->generate_error_name_table);
5224 assert(g->errors_by_index.length > 0);5234 assert(g->errors_by_index.length > 0);
52255235
...@@ -5346,7 +5356,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) {...@@ -5346,7 +5356,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) {
5346 return fn_val;5356 return fn_val;
5347}5357}
53485358
5349static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutableGen *executable,5359static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, Stage1Air *executable,
5350 IrInstGenTagName *instruction)5360 IrInstGenTagName *instruction)
5351{5361{
5352 ZigType *enum_type = instruction->target->value->type;5362 ZigType *enum_type = instruction->target->value->type;
...@@ -5359,7 +5369,7 @@ static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutableGen *executa...@@ -5359,7 +5369,7 @@ static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutableGen *executa
5359 get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, "");5369 get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, "");
5360}5370}
53615371
5362static LLVMValueRef ir_render_field_parent_ptr(CodeGen *g, IrExecutableGen *executable,5372static LLVMValueRef ir_render_field_parent_ptr(CodeGen *g, Stage1Air *executable,
5363 IrInstGenFieldParentPtr *instruction)5373 IrInstGenFieldParentPtr *instruction)
5364{5374{
5365 ZigType *container_ptr_type = instruction->base.value->type;5375 ZigType *container_ptr_type = instruction->base.value->type;
...@@ -5386,7 +5396,7 @@ static LLVMValueRef ir_render_field_parent_ptr(CodeGen *g, IrExecutableGen *exec...@@ -5386,7 +5396,7 @@ static LLVMValueRef ir_render_field_parent_ptr(CodeGen *g, IrExecutableGen *exec
5386 }5396 }
5387}5397}
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) {
5390 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);5400 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
5391 assert(target_val);5401 assert(target_val);
53925402
...@@ -5449,7 +5459,7 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutableGen *executable...@@ -5449,7 +5459,7 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutableGen *executable
5449 return target_val;5459 return target_val;
5450}5460}
54515461
5452static LLVMValueRef ir_render_error_return_trace(CodeGen *g, IrExecutableGen *executable,5462static LLVMValueRef ir_render_error_return_trace(CodeGen *g, Stage1Air *executable,
5453 IrInstGenErrorReturnTrace *instruction)5463 IrInstGenErrorReturnTrace *instruction)
5454{5464{
5455 bool is_llvm_alloca;5465 bool is_llvm_alloca;
...@@ -5522,7 +5532,7 @@ static LLVMTypeRef get_atomic_abi_type(CodeGen *g, IrInstGen *instruction, bool...@@ -5522,7 +5532,7 @@ static LLVMTypeRef get_atomic_abi_type(CodeGen *g, IrInstGen *instruction, bool
5522 }5532 }
5523}5533}
55245534
5525static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, IrInstGenCmpxchg *instruction) {5535static LLVMValueRef ir_render_cmpxchg(CodeGen *g, Stage1Air *executable, IrInstGenCmpxchg *instruction) {
5526 LLVMValueRef ptr_val = ir_llvm_value(g, instruction->ptr);5536 LLVMValueRef ptr_val = ir_llvm_value(g, instruction->ptr);
5527 LLVMValueRef cmp_val = ir_llvm_value(g, instruction->cmp_value);5537 LLVMValueRef cmp_val = ir_llvm_value(g, instruction->cmp_value);
5528 LLVMValueRef new_val = ir_llvm_value(g, instruction->new_value);5538 LLVMValueRef new_val = ir_llvm_value(g, instruction->new_value);
...@@ -5584,7 +5594,7 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, I...@@ -5584,7 +5594,7 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, I
5584 return result_loc;5594 return result_loc;
5585}5595}
55865596
5587static LLVMValueRef ir_render_reduce(CodeGen *g, IrExecutableGen *executable, IrInstGenReduce *instruction) {5597static LLVMValueRef ir_render_reduce(CodeGen *g, Stage1Air *executable, IrInstGenReduce *instruction) {
5588 LLVMValueRef value = ir_llvm_value(g, instruction->value);5598 LLVMValueRef value = ir_llvm_value(g, instruction->value);
55895599
5590 ZigType *value_type = instruction->value->value->type;5600 ZigType *value_type = instruction->value->value->type;
...@@ -5648,13 +5658,13 @@ static LLVMValueRef ir_render_reduce(CodeGen *g, IrExecutableGen *executable, Ir...@@ -5648,13 +5658,13 @@ static LLVMValueRef ir_render_reduce(CodeGen *g, IrExecutableGen *executable, Ir
5648 return result_val;5658 return result_val;
5649}5659}
56505660
5651static LLVMValueRef ir_render_fence(CodeGen *g, IrExecutableGen *executable, IrInstGenFence *instruction) {5661static LLVMValueRef ir_render_fence(CodeGen *g, Stage1Air *executable, IrInstGenFence *instruction) {
5652 LLVMAtomicOrdering atomic_order = to_LLVMAtomicOrdering(instruction->order);5662 LLVMAtomicOrdering atomic_order = to_LLVMAtomicOrdering(instruction->order);
5653 LLVMBuildFence(g->builder, atomic_order, false, "");5663 LLVMBuildFence(g->builder, atomic_order, false, "");
5654 return nullptr;5664 return nullptr;
5655}5665}
56565666
5657static LLVMValueRef ir_render_truncate(CodeGen *g, IrExecutableGen *executable, IrInstGenTruncate *instruction) {5667static LLVMValueRef ir_render_truncate(CodeGen *g, Stage1Air *executable, IrInstGenTruncate *instruction) {
5658 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);5668 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
5659 ZigType *dest_type = instruction->base.value->type;5669 ZigType *dest_type = instruction->base.value->type;
5660 ZigType *src_type = instruction->target->value->type;5670 ZigType *src_type = instruction->target->value->type;
...@@ -5669,7 +5679,7 @@ static LLVMValueRef ir_render_truncate(CodeGen *g, IrExecutableGen *executable,...@@ -5669,7 +5679,7 @@ static LLVMValueRef ir_render_truncate(CodeGen *g, IrExecutableGen *executable,
5669 }5679 }
5670}5680}
56715681
5672static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutableGen *executable, IrInstGenMemset *instruction) {5682static LLVMValueRef ir_render_memset(CodeGen *g, Stage1Air *executable, IrInstGenMemset *instruction) {
5673 LLVMValueRef dest_ptr = ir_llvm_value(g, instruction->dest_ptr);5683 LLVMValueRef dest_ptr = ir_llvm_value(g, instruction->dest_ptr);
5674 LLVMValueRef len_val = ir_llvm_value(g, instruction->count);5684 LLVMValueRef len_val = ir_llvm_value(g, instruction->count);
56755685
...@@ -5699,7 +5709,7 @@ static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutableGen *executable, Ir...@@ -5699,7 +5709,7 @@ static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutableGen *executable, Ir
5699 return nullptr;5709 return nullptr;
5700}5710}
57015711
5702static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutableGen *executable, IrInstGenMemcpy *instruction) {5712static LLVMValueRef ir_render_memcpy(CodeGen *g, Stage1Air *executable, IrInstGenMemcpy *instruction) {
5703 LLVMValueRef dest_ptr = ir_llvm_value(g, instruction->dest_ptr);5713 LLVMValueRef dest_ptr = ir_llvm_value(g, instruction->dest_ptr);
5704 LLVMValueRef src_ptr = ir_llvm_value(g, instruction->src_ptr);5714 LLVMValueRef src_ptr = ir_llvm_value(g, instruction->src_ptr);
5705 LLVMValueRef len_val = ir_llvm_value(g, instruction->count);5715 LLVMValueRef len_val = ir_llvm_value(g, instruction->count);
...@@ -5721,14 +5731,14 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutableGen *executable, Ir...@@ -5721,14 +5731,14 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutableGen *executable, Ir
5721 return nullptr;5731 return nullptr;
5722}5732}
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) {
5725 // TODO adjust for wasm645735 // TODO adjust for wasm64
5726 LLVMValueRef param = ir_llvm_value(g, instruction->index);5736 LLVMValueRef param = ir_llvm_value(g, instruction->index);
5727 LLVMValueRef val = LLVMBuildCall(g->builder, gen_wasm_memory_size(g), &param, 1, "");5737 LLVMValueRef val = LLVMBuildCall(g->builder, gen_wasm_memory_size(g), &param, 1, "");
5728 return val;5738 return val;
5729}5739}
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) {
5732 // TODO adjust for wasm645742 // TODO adjust for wasm64
5733 LLVMValueRef params[] = {5743 LLVMValueRef params[] = {
5734 ir_llvm_value(g, instruction->index),5744 ir_llvm_value(g, instruction->index),
...@@ -5738,7 +5748,7 @@ static LLVMValueRef ir_render_wasm_memory_grow(CodeGen *g, IrExecutableGen *exec...@@ -5738,7 +5748,7 @@ static LLVMValueRef ir_render_wasm_memory_grow(CodeGen *g, IrExecutableGen *exec
5738 return val;5748 return val;
5739}5749}
57405750
5741static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrInstGenSlice *instruction) {5751static LLVMValueRef ir_render_slice(CodeGen *g, Stage1Air *executable, IrInstGenSlice *instruction) {
5742 Error err;5752 Error err;
57435753
5744 LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->ptr);5754 LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->ptr);
...@@ -5975,12 +5985,12 @@ static LLVMValueRef get_trap_fn_val(CodeGen *g) {...@@ -5975,12 +5985,12 @@ static LLVMValueRef get_trap_fn_val(CodeGen *g) {
5975}5985}
59765986
59775987
5978static LLVMValueRef ir_render_breakpoint(CodeGen *g, IrExecutableGen *executable, IrInstGenBreakpoint *instruction) {5988static LLVMValueRef ir_render_breakpoint(CodeGen *g, Stage1Air *executable, IrInstGenBreakpoint *instruction) {
5979 LLVMBuildCall(g->builder, get_trap_fn_val(g), nullptr, 0, "");5989 LLVMBuildCall(g->builder, get_trap_fn_val(g), nullptr, 0, "");
5980 return nullptr;5990 return nullptr;
5981}5991}
59825992
5983static LLVMValueRef ir_render_return_address(CodeGen *g, IrExecutableGen *executable,5993static LLVMValueRef ir_render_return_address(CodeGen *g, Stage1Air *executable,
5984 IrInstGenReturnAddress *instruction)5994 IrInstGenReturnAddress *instruction)
5985{5995{
5986 if (target_is_wasm(g->zig_target) && g->zig_target->os != OsEmscripten) {5996 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) {...@@ -6008,7 +6018,7 @@ static LLVMValueRef get_frame_address_fn_val(CodeGen *g) {
6008 return g->frame_address_fn_val;6018 return g->frame_address_fn_val;
6009}6019}
60106020
6011static LLVMValueRef ir_render_frame_address(CodeGen *g, IrExecutableGen *executable,6021static LLVMValueRef ir_render_frame_address(CodeGen *g, Stage1Air *executable,
6012 IrInstGenFrameAddress *instruction)6022 IrInstGenFrameAddress *instruction)
6013{6023{
6014 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->llvm_type);6024 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->llvm_type);
...@@ -6016,7 +6026,7 @@ static LLVMValueRef ir_render_frame_address(CodeGen *g, IrExecutableGen *executa...@@ -6016,7 +6026,7 @@ static LLVMValueRef ir_render_frame_address(CodeGen *g, IrExecutableGen *executa
6016 return LLVMBuildPtrToInt(g->builder, ptr_val, g->builtin_types.entry_usize->llvm_type, "");6026 return LLVMBuildPtrToInt(g->builder, ptr_val, g->builtin_types.entry_usize->llvm_type, "");
6017}6027}
60186028
6019static LLVMValueRef ir_render_handle(CodeGen *g, IrExecutableGen *executable, IrInstGenFrameHandle *instruction) {6029static LLVMValueRef ir_render_handle(CodeGen *g, Stage1Air *executable, IrInstGenFrameHandle *instruction) {
6020 return g->cur_frame_ptr;6030 return g->cur_frame_ptr;
6021}6031}
60226032
...@@ -6045,7 +6055,7 @@ static LLVMValueRef render_shl_with_overflow(CodeGen *g, IrInstGenOverflowOp *in...@@ -6045,7 +6055,7 @@ static LLVMValueRef render_shl_with_overflow(CodeGen *g, IrInstGenOverflowOp *in
6045 return overflow_bit;6055 return overflow_bit;
6046}6056}
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) {
6049 AddSubMul add_sub_mul;6059 AddSubMul add_sub_mul;
6050 switch (instruction->op) {6060 switch (instruction->op) {
6051 case IrOverflowOpAdd:6061 case IrOverflowOpAdd:
...@@ -6083,7 +6093,7 @@ static LLVMValueRef ir_render_overflow_op(CodeGen *g, IrExecutableGen *executabl...@@ -6083,7 +6093,7 @@ static LLVMValueRef ir_render_overflow_op(CodeGen *g, IrExecutableGen *executabl
6083 return overflow_bit;6093 return overflow_bit;
6084}6094}
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) {
6087 ZigType *err_union_type = instruction->err_union->value->type;6097 ZigType *err_union_type = instruction->err_union->value->type;
6088 ZigType *payload_type = err_union_type->data.error_union.payload_type;6098 ZigType *payload_type = err_union_type->data.error_union.payload_type;
6089 LLVMValueRef err_union_handle = ir_llvm_value(g, instruction->err_union);6099 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,...@@ -6100,7 +6110,7 @@ static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutableGen *executable,
6100 return LLVMBuildICmp(g->builder, LLVMIntNE, err_val, zero, "");6110 return LLVMBuildICmp(g->builder, LLVMIntNE, err_val, zero, "");
6101}6111}
61026112
6103static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutableGen *executable,6113static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, Stage1Air *executable,
6104 IrInstGenUnwrapErrCode *instruction)6114 IrInstGenUnwrapErrCode *instruction)
6105{6115{
6106 if (instruction->base.value->special != ConstValSpecialRuntime)6116 if (instruction->base.value->special != ConstValSpecialRuntime)
...@@ -6120,7 +6130,7 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutableGen *execu...@@ -6120,7 +6130,7 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutableGen *execu
6120 }6130 }
6121}6131}
61226132
6123static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutableGen *executable,6133static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, Stage1Air *executable,
6124 IrInstGenUnwrapErrPayload *instruction)6134 IrInstGenUnwrapErrPayload *instruction)
6125{6135{
6126 Error err;6136 Error err;
...@@ -6189,7 +6199,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutableGen *ex...@@ -6189,7 +6199,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutableGen *ex
6189 }6199 }
6190}6200}
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) {
6193 ZigType *wanted_type = instruction->base.value->type;6203 ZigType *wanted_type = instruction->base.value->type;
61946204
6195 assert(wanted_type->id == ZigTypeIdOptional);6205 assert(wanted_type->id == ZigTypeIdOptional);
...@@ -6225,7 +6235,7 @@ static LLVMValueRef ir_render_optional_wrap(CodeGen *g, IrExecutableGen *executa...@@ -6225,7 +6235,7 @@ static LLVMValueRef ir_render_optional_wrap(CodeGen *g, IrExecutableGen *executa
6225 return result_loc;6235 return result_loc;
6226}6236}
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) {
6229 ZigType *wanted_type = instruction->base.value->type;6239 ZigType *wanted_type = instruction->base.value->type;
62306240
6231 assert(wanted_type->id == ZigTypeIdErrorUnion);6241 assert(wanted_type->id == ZigTypeIdErrorUnion);
...@@ -6245,7 +6255,7 @@ static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutableGen *executa...@@ -6245,7 +6255,7 @@ static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutableGen *executa
6245 return result_loc;6255 return result_loc;
6246}6256}
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) {
6249 ZigType *wanted_type = instruction->base.value->type;6259 ZigType *wanted_type = instruction->base.value->type;
62506260
6251 assert(wanted_type->id == ZigTypeIdErrorUnion);6261 assert(wanted_type->id == ZigTypeIdErrorUnion);
...@@ -6276,7 +6286,7 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutableGen *exec...@@ -6276,7 +6286,7 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutableGen *exec
6276 return result_loc;6286 return result_loc;
6277}6287}
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) {
6280 ZigType *union_type = instruction->value->value->type;6290 ZigType *union_type = instruction->value->value->type;
62816291
6282 ZigType *tag_type = union_type->data.unionation.tag_type;6292 ZigType *tag_type = union_type->data.unionation.tag_type;
...@@ -6294,14 +6304,14 @@ static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutableGen *executable,...@@ -6294,14 +6304,14 @@ static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutableGen *executable,
6294 return get_handle_value(g, tag_field_ptr, tag_type, ptr_type);6304 return get_handle_value(g, tag_field_ptr, tag_type, ptr_type);
6295}6305}
62966306
6297static LLVMValueRef ir_render_panic(CodeGen *g, IrExecutableGen *executable, IrInstGenPanic *instruction) {6307static LLVMValueRef ir_render_panic(CodeGen *g, Stage1Air *executable, IrInstGenPanic *instruction) {
6298 bool is_llvm_alloca;6308 bool is_llvm_alloca;
6299 LLVMValueRef err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.base.scope, &is_llvm_alloca);6309 LLVMValueRef err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.base.scope, &is_llvm_alloca);
6300 gen_panic(g, ir_llvm_value(g, instruction->msg), err_ret_trace_val, is_llvm_alloca);6310 gen_panic(g, ir_llvm_value(g, instruction->msg), err_ret_trace_val, is_llvm_alloca);
6301 return nullptr;6311 return nullptr;
6302}6312}
63036313
6304static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutableGen *executable,6314static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, Stage1Air *executable,
6305 IrInstGenAtomicRmw *instruction)6315 IrInstGenAtomicRmw *instruction)
6306{6316{
6307 bool is_signed;6317 bool is_signed;
...@@ -6353,7 +6363,7 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutableGen *executable...@@ -6353,7 +6363,7 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutableGen *executable
6353 return LLVMBuildIntToPtr(g->builder, uncasted_result, get_llvm_type(g, operand_type), "");6363 return LLVMBuildIntToPtr(g->builder, uncasted_result, get_llvm_type(g, operand_type), "");
6354}6364}
63556365
6356static LLVMValueRef ir_render_atomic_load(CodeGen *g, IrExecutableGen *executable,6366static LLVMValueRef ir_render_atomic_load(CodeGen *g, Stage1Air *executable,
6357 IrInstGenAtomicLoad *instruction)6367 IrInstGenAtomicLoad *instruction)
6358{6368{
6359 LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->ordering);6369 LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->ordering);
...@@ -6374,7 +6384,7 @@ static LLVMValueRef ir_render_atomic_load(CodeGen *g, IrExecutableGen *executabl...@@ -6374,7 +6384,7 @@ static LLVMValueRef ir_render_atomic_load(CodeGen *g, IrExecutableGen *executabl
6374 return load_inst;6384 return load_inst;
6375}6385}
63766386
6377static LLVMValueRef ir_render_atomic_store(CodeGen *g, IrExecutableGen *executable,6387static LLVMValueRef ir_render_atomic_store(CodeGen *g, Stage1Air *executable,
6378 IrInstGenAtomicStore *instruction)6388 IrInstGenAtomicStore *instruction)
6379{6389{
6380 LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->ordering);6390 LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->ordering);
...@@ -6397,13 +6407,13 @@ static LLVMValueRef ir_render_atomic_store(CodeGen *g, IrExecutableGen *executab...@@ -6397,13 +6407,13 @@ static LLVMValueRef ir_render_atomic_store(CodeGen *g, IrExecutableGen *executab
6397 return nullptr;6407 return nullptr;
6398}6408}
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) {
6401 LLVMValueRef operand = ir_llvm_value(g, instruction->operand);6411 LLVMValueRef operand = ir_llvm_value(g, instruction->operand);
6402 LLVMValueRef fn_val = get_float_fn(g, instruction->base.value->type, ZigLLVMFnIdFloatOp, instruction->fn_id);6412 LLVMValueRef fn_val = get_float_fn(g, instruction->base.value->type, ZigLLVMFnIdFloatOp, instruction->fn_id);
6403 return LLVMBuildCall(g->builder, fn_val, &operand, 1, "");6413 return LLVMBuildCall(g->builder, fn_val, &operand, 1, "");
6404}6414}
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) {
6407 LLVMValueRef op1 = ir_llvm_value(g, instruction->op1);6417 LLVMValueRef op1 = ir_llvm_value(g, instruction->op1);
6408 LLVMValueRef op2 = ir_llvm_value(g, instruction->op2);6418 LLVMValueRef op2 = ir_llvm_value(g, instruction->op2);
6409 LLVMValueRef op3 = ir_llvm_value(g, instruction->op3);6419 LLVMValueRef op3 = ir_llvm_value(g, instruction->op3);
...@@ -6418,7 +6428,7 @@ static LLVMValueRef ir_render_mul_add(CodeGen *g, IrExecutableGen *executable, I...@@ -6418,7 +6428,7 @@ static LLVMValueRef ir_render_mul_add(CodeGen *g, IrExecutableGen *executable, I
6418 return LLVMBuildCall(g->builder, fn_val, args, 3, "");6428 return LLVMBuildCall(g->builder, fn_val, args, 3, "");
6419}6429}
64206430
6421static LLVMValueRef ir_render_bswap(CodeGen *g, IrExecutableGen *executable, IrInstGenBswap *instruction) {6431static LLVMValueRef ir_render_bswap(CodeGen *g, Stage1Air *executable, IrInstGenBswap *instruction) {
6422 LLVMValueRef op = ir_llvm_value(g, instruction->op);6432 LLVMValueRef op = ir_llvm_value(g, instruction->op);
6423 ZigType *expr_type = instruction->base.value->type;6433 ZigType *expr_type = instruction->base.value->type;
6424 bool is_vector = expr_type->id == ZigTypeIdVector;6434 bool is_vector = expr_type->id == ZigTypeIdVector;
...@@ -6452,7 +6462,7 @@ static LLVMValueRef ir_render_bswap(CodeGen *g, IrExecutableGen *executable, IrI...@@ -6452,7 +6462,7 @@ static LLVMValueRef ir_render_bswap(CodeGen *g, IrExecutableGen *executable, IrI
6452 return LLVMBuildTrunc(g->builder, shifted, get_llvm_type(g, expr_type), "");6462 return LLVMBuildTrunc(g->builder, shifted, get_llvm_type(g, expr_type), "");
6453}6463}
64546464
6455static LLVMValueRef ir_render_extern(CodeGen *g, IrExecutableGen *executable,6465static LLVMValueRef ir_render_extern(CodeGen *g, Stage1Air *executable,
6456 IrInstGenExtern *instruction)6466 IrInstGenExtern *instruction)
6457{6467{
6458 ZigType *expr_type = instruction->base.value->type;6468 ZigType *expr_type = instruction->base.value->type;
...@@ -6476,7 +6486,7 @@ static LLVMValueRef ir_render_extern(CodeGen *g, IrExecutableGen *executable,...@@ -6476,7 +6486,7 @@ static LLVMValueRef ir_render_extern(CodeGen *g, IrExecutableGen *executable,
6476 return LLVMBuildBitCast(g->builder, global_value, get_llvm_type(g, expr_type), "");6486 return LLVMBuildBitCast(g->builder, global_value, get_llvm_type(g, expr_type), "");
6477}6487}
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) {
6480 LLVMValueRef op = ir_llvm_value(g, instruction->op);6490 LLVMValueRef op = ir_llvm_value(g, instruction->op);
6481 ZigType *int_type = instruction->base.value->type;6491 ZigType *int_type = instruction->base.value->type;
6482 assert(int_type->id == ZigTypeIdInt);6492 assert(int_type->id == ZigTypeIdInt);
...@@ -6484,7 +6494,7 @@ static LLVMValueRef ir_render_bit_reverse(CodeGen *g, IrExecutableGen *executabl...@@ -6484,7 +6494,7 @@ static LLVMValueRef ir_render_bit_reverse(CodeGen *g, IrExecutableGen *executabl
6484 return LLVMBuildCall(g->builder, fn_val, &op, 1, "");6494 return LLVMBuildCall(g->builder, fn_val, &op, 1, "");
6485}6495}
64866496
6487static LLVMValueRef ir_render_vector_to_array(CodeGen *g, IrExecutableGen *executable,6497static LLVMValueRef ir_render_vector_to_array(CodeGen *g, Stage1Air *executable,
6488 IrInstGenVectorToArray *instruction)6498 IrInstGenVectorToArray *instruction)
6489{6499{
6490 ZigType *array_type = instruction->base.value->type;6500 ZigType *array_type = instruction->base.value->type;
...@@ -6518,7 +6528,7 @@ static LLVMValueRef ir_render_vector_to_array(CodeGen *g, IrExecutableGen *execu...@@ -6518,7 +6528,7 @@ static LLVMValueRef ir_render_vector_to_array(CodeGen *g, IrExecutableGen *execu
6518 return result_loc;6528 return result_loc;
6519}6529}
65206530
6521static LLVMValueRef ir_render_array_to_vector(CodeGen *g, IrExecutableGen *executable,6531static LLVMValueRef ir_render_array_to_vector(CodeGen *g, Stage1Air *executable,
6522 IrInstGenArrayToVector *instruction)6532 IrInstGenArrayToVector *instruction)
6523{6533{
6524 ZigType *vector_type = instruction->base.value->type;6534 ZigType *vector_type = instruction->base.value->type;
...@@ -6555,7 +6565,7 @@ static LLVMValueRef ir_render_array_to_vector(CodeGen *g, IrExecutableGen *execu...@@ -6555,7 +6565,7 @@ static LLVMValueRef ir_render_array_to_vector(CodeGen *g, IrExecutableGen *execu
6555 }6565 }
6556}6566}
65576567
6558static LLVMValueRef ir_render_assert_zero(CodeGen *g, IrExecutableGen *executable,6568static LLVMValueRef ir_render_assert_zero(CodeGen *g, Stage1Air *executable,
6559 IrInstGenAssertZero *instruction)6569 IrInstGenAssertZero *instruction)
6560{6570{
6561 LLVMValueRef target = ir_llvm_value(g, instruction->target);6571 LLVMValueRef target = ir_llvm_value(g, instruction->target);
...@@ -6566,7 +6576,7 @@ static LLVMValueRef ir_render_assert_zero(CodeGen *g, IrExecutableGen *executabl...@@ -6566,7 +6576,7 @@ static LLVMValueRef ir_render_assert_zero(CodeGen *g, IrExecutableGen *executabl
6566 return nullptr;6576 return nullptr;
6567}6577}
65686578
6569static LLVMValueRef ir_render_assert_non_null(CodeGen *g, IrExecutableGen *executable,6579static LLVMValueRef ir_render_assert_non_null(CodeGen *g, Stage1Air *executable,
6570 IrInstGenAssertNonNull *instruction)6580 IrInstGenAssertNonNull *instruction)
6571{6581{
6572 LLVMValueRef target = ir_llvm_value(g, instruction->target);6582 LLVMValueRef target = ir_llvm_value(g, instruction->target);
...@@ -6591,7 +6601,7 @@ static LLVMValueRef ir_render_assert_non_null(CodeGen *g, IrExecutableGen *execu...@@ -6591,7 +6601,7 @@ static LLVMValueRef ir_render_assert_non_null(CodeGen *g, IrExecutableGen *execu
6591 return nullptr;6601 return nullptr;
6592}6602}
65936603
6594static LLVMValueRef ir_render_suspend_begin(CodeGen *g, IrExecutableGen *executable,6604static LLVMValueRef ir_render_suspend_begin(CodeGen *g, Stage1Air *executable,
6595 IrInstGenSuspendBegin *instruction)6605 IrInstGenSuspendBegin *instruction)
6596{6606{
6597 if (fn_is_async(g->cur_fn)) {6607 if (fn_is_async(g->cur_fn)) {
...@@ -6600,7 +6610,7 @@ static LLVMValueRef ir_render_suspend_begin(CodeGen *g, IrExecutableGen *executa...@@ -6600,7 +6610,7 @@ static LLVMValueRef ir_render_suspend_begin(CodeGen *g, IrExecutableGen *executa
6600 return nullptr;6610 return nullptr;
6601}6611}
66026612
6603static LLVMValueRef ir_render_suspend_finish(CodeGen *g, IrExecutableGen *executable,6613static LLVMValueRef ir_render_suspend_finish(CodeGen *g, Stage1Air *executable,
6604 IrInstGenSuspendFinish *instruction)6614 IrInstGenSuspendFinish *instruction)
6605{6615{
6606 LLVMBuildRetVoid(g->builder);6616 LLVMBuildRetVoid(g->builder);
...@@ -6652,7 +6662,7 @@ static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstGen *source_instr,...@@ -6652,7 +6662,7 @@ static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstGen *source_instr,
6652 }6662 }
6653}6663}
66546664
6655static LLVMValueRef ir_render_await(CodeGen *g, IrExecutableGen *executable, IrInstGenAwait *instruction) {6665static LLVMValueRef ir_render_await(CodeGen *g, Stage1Air *executable, IrInstGenAwait *instruction) {
6656 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;6666 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
6657 LLVMValueRef zero = LLVMConstNull(usize_type_ref);6667 LLVMValueRef zero = LLVMConstNull(usize_type_ref);
6658 LLVMValueRef target_frame_ptr = ir_llvm_value(g, instruction->frame);6668 LLVMValueRef target_frame_ptr = ir_llvm_value(g, instruction->frame);
...@@ -6739,7 +6749,7 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutableGen *executable, IrI...@@ -6739,7 +6749,7 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutableGen *executable, IrI
6739 return nullptr;6749 return nullptr;
6740}6750}
67416751
6742static LLVMValueRef ir_render_resume(CodeGen *g, IrExecutableGen *executable, IrInstGenResume *instruction) {6752static LLVMValueRef ir_render_resume(CodeGen *g, Stage1Air *executable, IrInstGenResume *instruction) {
6743 LLVMValueRef frame = ir_llvm_value(g, instruction->frame);6753 LLVMValueRef frame = ir_llvm_value(g, instruction->frame);
6744 ZigType *frame_type = instruction->frame->value->type;6754 ZigType *frame_type = instruction->frame->value->type;
6745 assert(frame_type->id == ZigTypeIdAnyFrame);6755 assert(frame_type->id == ZigTypeIdAnyFrame);
...@@ -6748,14 +6758,14 @@ static LLVMValueRef ir_render_resume(CodeGen *g, IrExecutableGen *executable, Ir...@@ -6748,14 +6758,14 @@ static LLVMValueRef ir_render_resume(CodeGen *g, IrExecutableGen *executable, Ir
6748 return nullptr;6758 return nullptr;
6749}6759}
67506760
6751static LLVMValueRef ir_render_frame_size(CodeGen *g, IrExecutableGen *executable,6761static LLVMValueRef ir_render_frame_size(CodeGen *g, Stage1Air *executable,
6752 IrInstGenFrameSize *instruction)6762 IrInstGenFrameSize *instruction)
6753{6763{
6754 LLVMValueRef fn_val = ir_llvm_value(g, instruction->fn);6764 LLVMValueRef fn_val = ir_llvm_value(g, instruction->fn);
6755 return gen_frame_size(g, fn_val);6765 return gen_frame_size(g, fn_val);
6756}6766}
67576767
6758static LLVMValueRef ir_render_spill_begin(CodeGen *g, IrExecutableGen *executable,6768static LLVMValueRef ir_render_spill_begin(CodeGen *g, Stage1Air *executable,
6759 IrInstGenSpillBegin *instruction)6769 IrInstGenSpillBegin *instruction)
6760{6770{
6761 if (!fn_is_async(g->cur_fn))6771 if (!fn_is_async(g->cur_fn))
...@@ -6775,7 +6785,7 @@ static LLVMValueRef ir_render_spill_begin(CodeGen *g, IrExecutableGen *executabl...@@ -6775,7 +6785,7 @@ static LLVMValueRef ir_render_spill_begin(CodeGen *g, IrExecutableGen *executabl
6775 zig_unreachable();6785 zig_unreachable();
6776}6786}
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) {
6779 if (!fn_is_async(g->cur_fn))6789 if (!fn_is_async(g->cur_fn))
6780 return ir_llvm_value(g, instruction->begin->operand);6790 return ir_llvm_value(g, instruction->begin->operand);
67816791
...@@ -6791,7 +6801,7 @@ static LLVMValueRef ir_render_spill_end(CodeGen *g, IrExecutableGen *executable,...@@ -6791,7 +6801,7 @@ static LLVMValueRef ir_render_spill_end(CodeGen *g, IrExecutableGen *executable,
6791 zig_unreachable();6801 zig_unreachable();
6792}6802}
67936803
6794static LLVMValueRef ir_render_vector_extract_elem(CodeGen *g, IrExecutableGen *executable,6804static LLVMValueRef ir_render_vector_extract_elem(CodeGen *g, Stage1Air *executable,
6795 IrInstGenVectorExtractElem *instruction)6805 IrInstGenVectorExtractElem *instruction)
6796{6806{
6797 LLVMValueRef vector = ir_llvm_value(g, instruction->vector);6807 LLVMValueRef vector = ir_llvm_value(g, instruction->vector);
...@@ -6806,11 +6816,11 @@ static void set_debug_location(CodeGen *g, IrInstGen *instruction) {...@@ -6806,11 +6816,11 @@ static void set_debug_location(CodeGen *g, IrInstGen *instruction) {
6806 assert(source_node);6816 assert(source_node);
6807 assert(scope);6817 assert(scope);
68086818
6809 ZigLLVMSetCurrentDebugLocation(g->builder, (int)source_node->line + 1,6819 ZigLLVMSetCurrentDebugLocation(g->builder, node_line_onebased(source_node),
6810 (int)source_node->column + 1, get_di_scope(g, scope));6820 node_column_onebased(source_node), get_di_scope(g, scope));
6811}6821}
68126822
6813static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutableGen *executable, IrInstGen *instruction) {6823static LLVMValueRef ir_render_instruction(CodeGen *g, Stage1Air *executable, IrInstGen *instruction) {
6814 switch (instruction->id) {6824 switch (instruction->id) {
6815 case IrInstGenIdInvalid:6825 case IrInstGenIdInvalid:
6816 case IrInstGenIdConst:6826 case IrInstGenIdConst:
...@@ -6998,7 +7008,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutableGen *executabl...@@ -6998,7 +7008,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutableGen *executabl
6998static void ir_render(CodeGen *g, ZigFn *fn_entry) {7008static void ir_render(CodeGen *g, ZigFn *fn_entry) {
6999 assert(fn_entry);7009 assert(fn_entry);
70007010
7001 IrExecutableGen *executable = &fn_entry->analyzed_executable;7011 Stage1Air *executable = &fn_entry->analyzed_executable;
7002 assert(executable->basic_block_list.length > 0);7012 assert(executable->basic_block_list.length > 0);
70037013
7004 for (size_t block_i = 0; block_i < executable->basic_block_list.length; block_i += 1) {7014 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) {...@@ -7996,7 +8006,7 @@ static void generate_error_name_table(CodeGen *g) {
7996}8006}
79978007
7998static void build_all_basic_blocks(CodeGen *g, ZigFn *fn) {8008static void build_all_basic_blocks(CodeGen *g, ZigFn *fn) {
7999 IrExecutableGen *executable = &fn->analyzed_executable;8009 Stage1Air *executable = &fn->analyzed_executable;
8000 assert(executable->basic_block_list.length > 0);8010 assert(executable->basic_block_list.length > 0);
8001 LLVMValueRef fn_val = fn_llvm_value(g, fn);8011 LLVMValueRef fn_val = fn_llvm_value(g, fn);
8002 LLVMBasicBlockRef first_bb = nullptr;8012 LLVMBasicBlockRef first_bb = nullptr;
...@@ -8030,7 +8040,7 @@ static void gen_global_var(CodeGen *g, ZigVar *var, LLVMValueRef init_val,...@@ -8030,7 +8040,7 @@ static void gen_global_var(CodeGen *g, ZigVar *var, LLVMValueRef init_val,
8030 bool is_local_to_unit = true;8040 bool is_local_to_unit = true;
8031 ZigLLVMCreateGlobalVariable(g->dbuilder, get_di_scope(g, var->parent_scope), var->name,8041 ZigLLVMCreateGlobalVariable(g->dbuilder, get_di_scope(g, var->parent_scope), var->name,
8032 var->name, import->data.structure.root_struct->di_file,8042 var->name, import->data.structure.root_struct->di_file,
8033 (unsigned)(var->decl_node->line + 1),8043 node_line_onebased(var->decl_node),
8034 get_llvm_di_type(g, type_entry), is_local_to_unit);8044 get_llvm_di_type(g, type_entry), is_local_to_unit);
80358045
8036 // TODO ^^ make an actual global variable8046 // TODO ^^ make an actual global variable
...@@ -8305,7 +8315,8 @@ static void do_code_gen(CodeGen *g) {...@@ -8305,7 +8315,8 @@ static void do_code_gen(CodeGen *g) {
83058315
8306 if (var->src_arg_index == SIZE_MAX) {8316 if (var->src_arg_index == SIZE_MAX) {
8307 var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),8317 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),
8309 get_llvm_di_type(g, var->var_type), !g->strip_debug_symbols, 0);8320 get_llvm_di_type(g, var->var_type), !g->strip_debug_symbols, 0);
83108321
8311 } else if (is_c_abi) {8322 } else if (is_c_abi) {
...@@ -8330,7 +8341,7 @@ static void do_code_gen(CodeGen *g) {...@@ -8330,7 +8341,7 @@ static void do_code_gen(CodeGen *g) {
8330 if (var->decl_node) {8341 if (var->decl_node) {
8331 var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope),8342 var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
8332 var->name, import->data.structure.root_struct->di_file,8343 var->name, import->data.structure.root_struct->di_file,
8333 (unsigned)(var->decl_node->line + 1),8344 node_line_onebased(var->decl_node),
8334 get_llvm_di_type(g, gen_type), !g->strip_debug_symbols, 0, (unsigned)(gen_info->gen_index+1));8345 get_llvm_di_type(g, gen_type), !g->strip_debug_symbols, 0, (unsigned)(gen_info->gen_index+1));
8335 }8346 }
83368347
...@@ -8374,10 +8385,11 @@ static void do_code_gen(CodeGen *g) {...@@ -8374,10 +8385,11 @@ static void do_code_gen(CodeGen *g) {
83748385
8375 if (!g->strip_debug_symbols) {8386 if (!g->strip_debug_symbols) {
8376 AstNode *source_node = fn_table_entry->proto_node;8387 AstNode *source_node = fn_table_entry->proto_node;
8377 ZigLLVMSetCurrentDebugLocation(g->builder, (int)source_node->line + 1,8388 ZigLLVMSetCurrentDebugLocation(g->builder,
8378 (int)source_node->column + 1, get_di_scope(g, fn_table_entry->child_scope));8389 node_line_onebased(source_node), node_column_onebased(source_node),
8390 get_di_scope(g, fn_table_entry->child_scope));
8379 }8391 }
8380 IrExecutableGen *executable = &fn_table_entry->analyzed_executable;8392 Stage1Air *executable = &fn_table_entry->analyzed_executable;
8381 LLVMBasicBlockRef bad_resume_block = LLVMAppendBasicBlock(g->cur_fn_val, "BadResume");8393 LLVMBasicBlockRef bad_resume_block = LLVMAppendBasicBlock(g->cur_fn_val, "BadResume");
8382 LLVMPositionBuilderAtEnd(g->builder, bad_resume_block);8394 LLVMPositionBuilderAtEnd(g->builder, bad_resume_block);
8383 gen_assertion_scope(g, PanicMsgIdBadResume, fn_table_entry->child_scope);8395 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) {...@@ -1084,19 +1084,43 @@ static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) {
1084 jw_end_object(jw);1084 jw_end_object(jw);
1085}1085}
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
1087static void anal_dump_node(AnalDumpCtx *ctx, const AstNode *node) {1110static void anal_dump_node(AnalDumpCtx *ctx, const AstNode *node) {
1088 JsonWriter *jw = &ctx->jw;1111 JsonWriter *jw = &ctx->jw;
10891112
1090 jw_begin_object(jw);1113 jw_begin_object(jw);
10911114
1092 jw_object_field(jw, "file");1115 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
1095 jw_object_field(jw, "line");1119 jw_object_field(jw, "line");
1096 jw_int(jw, node->line);1120 jw_int(jw, root_struct->token_locs[node->main_token].line);
10971121
1098 jw_object_field(jw, "col");1122 jw_object_field(jw, "col");
1099 jw_int(jw, node->column);1123 jw_int(jw, root_struct->token_locs[node->main_token].column);
11001124
1101 const Buf *doc_comments_buf = nullptr;1125 const Buf *doc_comments_buf = nullptr;
1102 const Buf *name_buf = nullptr;1126 const Buf *name_buf = nullptr;
...@@ -1107,30 +1131,30 @@ static void anal_dump_node(AnalDumpCtx *ctx, const AstNode *node) {...@@ -1107,30 +1131,30 @@ static void anal_dump_node(AnalDumpCtx *ctx, const AstNode *node) {
11071131
1108 switch (node->type) {1132 switch (node->type) {
1109 case NodeTypeParamDecl:1133 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);
1111 name_buf = node->data.param_decl.name;1135 name_buf = node->data.param_decl.name;
1112 is_var_args = node->data.param_decl.is_var_args;1136 is_var_args = node->data.param_decl.is_var_args;
1113 is_noalias = node->data.param_decl.is_noalias;1137 is_noalias = node->data.param_decl.is_noalias;
1114 is_comptime = node->data.param_decl.is_comptime;1138 is_comptime = node->data.param_decl.is_comptime;
1115 break;1139 break;
1116 case NodeTypeFnProto:1140 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);
1118 field_nodes = &node->data.fn_proto.params;1142 field_nodes = &node->data.fn_proto.params;
1119 is_var_args = node->data.fn_proto.is_var_args;1143 is_var_args = node->data.fn_proto.is_var_args;
1120 break;1144 break;
1121 case NodeTypeVariableDeclaration:1145 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);
1123 break;1147 break;
1124 case NodeTypeErrorSetField:1148 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);
1126 break;1150 break;
1127 case NodeTypeStructField:1151 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);
1129 name_buf = node->data.struct_field.name;1153 name_buf = node->data.struct_field.name;
1130 break;1154 break;
1131 case NodeTypeContainerDecl:1155 case NodeTypeContainerDecl:
1132 field_nodes = &node->data.container_decl.fields;1156 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);
1134 break;1158 break;
1135 default:1159 default:
1136 break;1160 break;
src/stage1/errmsg.cpp+19-40
...@@ -96,14 +96,14 @@ void err_msg_add_note(ErrorMsg *parent, ErrorMsg *note) {...@@ -96,14 +96,14 @@ void err_msg_add_note(ErrorMsg *parent, ErrorMsg *note) {
96 parent->notes.append(note);96 parent->notes.append(note);
97}97}
9898
99ErrorMsg *err_msg_create_with_offset(Buf *path, size_t line, size_t column, size_t offset,99ErrorMsg *err_msg_create_with_offset(Buf *path, uint32_t byte_offset, const char *source,
100 const char *source, Buf *msg)100 Buf *msg)
101{101{
102 ErrorMsg *err_msg = heap::c_allocator.create<ErrorMsg>();102 ErrorMsg *err_msg = heap::c_allocator.create<ErrorMsg>();
103 err_msg->path = path;103 err_msg->path = path;
104 err_msg->line_start = line;
105 err_msg->column_start = column;
106 err_msg->msg = msg;104 err_msg->msg = msg;
105 err_msg->line_start = 0;
106 err_msg->column_start = 0;
107107
108 if (source == nullptr) {108 if (source == nullptr) {
109 // Must initialize the buffer anyway109 // Must initialize the buffer anyway
...@@ -111,46 +111,25 @@ ErrorMsg *err_msg_create_with_offset(Buf *path, size_t line, size_t column, size...@@ -111,46 +111,25 @@ ErrorMsg *err_msg_create_with_offset(Buf *path, size_t line, size_t column, size
111 return err_msg;111 return err_msg;
112 }112 }
113113
114 size_t line_start_offset = offset;114 size_t line_start = 0;
115 for (;;) {115 size_t i = 0;
116 if (line_start_offset == 0) {116 for (;i < byte_offset; i += 1) {
117 break;117 switch (source[i]) {
118 }118 case '\n':
119119 err_msg->line_start += 1;
120 line_start_offset -= 1;120 err_msg->column_start = 0;
121121 line_start = i + 1;
122 if (source[line_start_offset] == '\n') {122 continue;
123 line_start_offset += 1;123 default:
124 break;124 err_msg->column_start += 1;
125 continue;
125 }126 }
126 }127 }
127128 while (source[i] != '\n' && source[i] != 0) {
128 size_t line_end_offset = offset;129 i += 1;
129 while (source[line_end_offset] && source[line_end_offset] != '\n') {
130 line_end_offset += 1;
131 }130 }
132131
133 buf_init_from_mem(&err_msg->line_buf, source + line_start_offset, line_end_offset - line_start_offset);132 buf_init_from_mem(&err_msg->line_buf, source + line_start, i - line_start);
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);
154133
155 return err_msg;134 return err_msg;
156}135}
src/stage1/errmsg.hpp+1-5
...@@ -25,10 +25,6 @@ struct ErrorMsg {...@@ -25,10 +25,6 @@ struct ErrorMsg {
25void print_err_msg(ErrorMsg *msg, ErrColor color);25void print_err_msg(ErrorMsg *msg, ErrColor color);
2626
27void err_msg_add_note(ErrorMsg *parent, ErrorMsg *note);27void 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,28ErrorMsg *err_msg_create_with_offset(Buf *path, uint32_t byte_offset, const char *source, Buf *msg);
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);
3329
34#endif30#endif
src/stage1/error.cpp+2
...@@ -88,6 +88,8 @@ const char *err_str(Error err) {...@@ -88,6 +88,8 @@ const char *err_str(Error err) {
88 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.";88 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.";
89 case ErrorFileBusy: return "file is busy";89 case ErrorFileBusy: return "file is busy";
90 case ErrorLocked: return "file is locked by another process";90 case ErrorLocked: return "file is locked by another process";
91 case ErrorInvalidCharacter: return "invalid character";
92 case ErrorUnicodePointTooLarge: return "unicode codepoint too large";
91 }93 }
92 return "(invalid error)";94 return "(invalid error)";
93}95}
src/stage1/ir.cpp+1336-9376
...@@ -5,8 +5,8 @@...@@ -5,8 +5,8 @@
5 * See http://opensource.org/licenses/MIT5 * See http://opensource.org/licenses/MIT
6 */6 */
77
8#include "astgen.hpp"
8#include "analyze.hpp"9#include "analyze.hpp"
9#include "ast_render.hpp"
10#include "error.hpp"10#include "error.hpp"
11#include "ir.hpp"11#include "ir.hpp"
12#include "ir_print.hpp"12#include "ir_print.hpp"
...@@ -22,16 +22,9 @@...@@ -22,16 +22,9 @@
22#include <errno.h>22#include <errno.h>
23#include <math.h>23#include <math.h>
2424
25struct IrBuilderSrc {
26 CodeGen *codegen;
27 IrExecutableSrc *exec;
28 IrBasicBlockSrc *current_basic_block;
29 AstNode *main_block_node;
30};
31
32struct IrBuilderGen {25struct IrBuilderGen {
33 CodeGen *codegen;26 CodeGen *codegen;
34 IrExecutableGen *exec;27 Stage1Air *exec;
35 IrBasicBlockGen *current_basic_block;28 IrBasicBlockGen *current_basic_block;
3629
37 // track for immediate post-analysis destruction30 // track for immediate post-analysis destruction
...@@ -40,7 +33,8 @@ struct IrBuilderGen {...@@ -40,7 +33,8 @@ struct IrBuilderGen {
4033
41struct IrAnalyze {34struct IrAnalyze {
42 CodeGen *codegen;35 CodeGen *codegen;
43 IrBuilderSrc old_irb;36 Stage1Zir *zir;
37 Stage1ZirBasicBlock *zir_current_basic_block;
44 IrBuilderGen new_irb;38 IrBuilderGen new_irb;
45 size_t old_bb_index;39 size_t old_bb_index;
46 size_t instruction_index;40 size_t instruction_index;
...@@ -48,10 +42,14 @@ struct IrAnalyze {...@@ -48,10 +42,14 @@ struct IrAnalyze {
48 AstNode *explicit_return_type_source_node;42 AstNode *explicit_return_type_source_node;
49 ZigList<IrInstGen *> src_implicit_return_type_list;43 ZigList<IrInstGen *> src_implicit_return_type_list;
50 ZigList<IrSuspendPosition> resume_stack;44 ZigList<IrSuspendPosition> resume_stack;
51 IrBasicBlockSrc *const_predecessor_bb;45 Stage1ZirBasicBlock *const_predecessor_bb;
52 size_t ref_count;46 size_t ref_count;
53 size_t break_debug_id; // for debugging purposes47 size_t break_debug_id; // for debugging purposes
54 IrInstGen *return_ptr;48 IrInstGen *return_ptr;
49 Stage1Air *parent_exec;
50 size_t *backward_branch_count;
51 size_t *backward_branch_quota;
52 ZigFn *fn;
5553
56 // For the purpose of using in a debugger54 // For the purpose of using in a debugger
57 void dump();55 void dump();
...@@ -216,27 +214,18 @@ struct DbgIrBreakPoint {...@@ -216,27 +214,18 @@ struct DbgIrBreakPoint {
216 const char *src_file;214 const char *src_file;
217 uint32_t line;215 uint32_t line;
218};216};
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);
225static IrInstGen *ir_implicit_cast(IrAnalyze *ira, IrInstGen *value, ZigType *expected_type);218static IrInstGen *ir_implicit_cast(IrAnalyze *ira, IrInstGen *value, ZigType *expected_type);
226static IrInstGen *ir_implicit_cast2(IrAnalyze *ira, IrInst *value_source_instr,219static IrInstGen *ir_implicit_cast2(IrAnalyze *ira, IrInst *value_source_instr,
227 IrInstGen *value, ZigType *expected_type);220 IrInstGen *value, ZigType *expected_type);
228static IrInstGen *ir_get_deref(IrAnalyze *ira, IrInst *source_instr, IrInstGen *ptr,221static IrInstGen *ir_get_deref(IrAnalyze *ira, IrInst *source_instr, IrInstGen *ptr,
229 ResultLoc *result_loc);222 ResultLoc *result_loc);
230static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutableSrc *exec, AstNode *source_node, Buf *msg);
231static IrInstGen *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name,223static IrInstGen *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name,
232 IrInst* source_instr, IrInstGen *container_ptr, IrInst *container_ptr_src,224 IrInst* source_instr, IrInstGen *container_ptr, IrInst *container_ptr_src,
233 ZigType *container_type, bool initializing);225 ZigType *container_type, bool initializing);
234static void ir_assert_impl(bool ok, IrInst* source_instruction, const char *file, unsigned int line);
235static void ir_assert_gen_impl(bool ok, IrInstGen *source_instruction, const char *file, unsigned int line);226static void ir_assert_gen_impl(bool ok, IrInstGen *source_instruction, const char *file, unsigned int line);
236static IrInstGen *ir_get_var_ptr(IrAnalyze *ira, IrInst *source_instr, ZigVar *var);227static IrInstGen *ir_get_var_ptr(IrAnalyze *ira, IrInst *source_instr, ZigVar *var);
237static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op);228static 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);
240static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align);229static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align);
241static ZigType *adjust_ptr_const(CodeGen *g, ZigType *ptr_type, bool is_const);230static ZigType *adjust_ptr_const(CodeGen *g, ZigType *ptr_type, bool is_const);
242static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align);231static 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...@@ -265,26 +254,14 @@ static IrInstGen *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInst* source_inst
265 IrInstGen *base_ptr, bool initializing);254 IrInstGen *base_ptr, bool initializing);
266static IrInstGen *ir_analyze_store_ptr(IrAnalyze *ira, IrInst* source_instr,255static IrInstGen *ir_analyze_store_ptr(IrAnalyze *ira, IrInst* source_instr,
267 IrInstGen *ptr, IrInstGen *uncasted_value, bool allow_write_through_const);256 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);
271static void ir_reset_result(ResultLoc *result_loc);257static 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);
276static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_instr,258static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_instr,
277 TypeStructField *field, IrInstGen *struct_ptr, ZigType *struct_type, bool initializing);259 TypeStructField *field, IrInstGen *struct_ptr, ZigType *struct_type, bool initializing);
278static IrInstGen *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name,260static IrInstGen *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name,
279 IrInst* source_instr, IrInstGen *container_ptr, ZigType *container_type);261 IrInst* source_instr, IrInstGen *container_ptr, ZigType *container_type);
280static ResultLoc *no_result_loc(void);
281static IrInstGen *ir_analyze_test_non_null(IrAnalyze *ira, IrInst *source_inst, IrInstGen *value);262static IrInstGen *ir_analyze_test_non_null(IrAnalyze *ira, IrInst *source_inst, IrInstGen *value);
282static IrInstGen *ir_error_dependency_loop(IrAnalyze *ira, IrInst *source_instr);263static IrInstGen *ir_error_dependency_loop(IrAnalyze *ira, IrInst *source_instr);
283static IrInstGen *ir_const_undef(IrAnalyze *ira, IrInst *source_instruction, ZigType *ty);264static 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);
288static IrInstGen *ir_analyze_union_init(IrAnalyze *ira, IrInst* source_instruction,265static IrInstGen *ir_analyze_union_init(IrAnalyze *ira, IrInst* source_instruction,
289 AstNode *field_source_node, ZigType *union_type, Buf *field_name, IrInstGen *field_result_loc,266 AstNode *field_source_node, ZigType *union_type, Buf *field_name, IrInstGen *field_result_loc,
290 IrInstGen *result_loc);267 IrInstGen *result_loc);
...@@ -295,292 +272,15 @@ static bool value_cmp_numeric_val_all(ZigValue *left, Cmp predicate, ZigValue *r...@@ -295,292 +272,15 @@ static bool value_cmp_numeric_val_all(ZigValue *left, Cmp predicate, ZigValue *r
295static void memoize_field_init_val(CodeGen *codegen, ZigType *container_type, TypeStructField *field);272static void memoize_field_init_val(CodeGen *codegen, ZigType *container_type, TypeStructField *field);
296static void value_to_bigfloat(BigFloat *out, ZigValue *val);273static 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
298#define ir_assert(OK, SOURCE_INSTRUCTION) ir_assert_impl((OK), (SOURCE_INSTRUCTION), __FILE__, __LINE__)281#define ir_assert(OK, SOURCE_INSTRUCTION) ir_assert_impl((OK), (SOURCE_INSTRUCTION), __FILE__, __LINE__)
299#define ir_assert_gen(OK, SOURCE_INSTRUCTION) ir_assert_gen_impl((OK), (SOURCE_INSTRUCTION), __FILE__, __LINE__)282#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
584void destroy_instruction_gen(IrInstGen *inst) {284void destroy_instruction_gen(IrInstGen *inst) {
585 switch (inst->id) {285 switch (inst->id) {
586 case IrInstGenIdInvalid:286 case IrInstGenIdInvalid:
...@@ -781,17 +481,17 @@ static void ira_deref(IrAnalyze *ira) {...@@ -781,17 +481,17 @@ static void ira_deref(IrAnalyze *ira) {
781 }481 }
782 assert(ira->ref_count != 0);482 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) {484 for (size_t bb_i = 0; bb_i < ira->zir->basic_block_list.length; bb_i += 1) {
785 IrBasicBlockSrc *pass1_bb = ira->old_irb.exec->basic_block_list.items[bb_i];485 Stage1ZirBasicBlock *pass1_bb = ira->zir->basic_block_list.items[bb_i];
786 for (size_t inst_i = 0; inst_i < pass1_bb->instruction_list.length; inst_i += 1) {486 for (size_t inst_i = 0; inst_i < pass1_bb->instruction_list.length; inst_i += 1) {
787 IrInstSrc *pass1_inst = pass1_bb->instruction_list.items[inst_i];487 IrInstSrc *pass1_inst = pass1_bb->instruction_list.items[inst_i];
788 destroy_instruction_src(pass1_inst);488 destroy_instruction_src(pass1_inst);
789 }489 }
790 heap::c_allocator.destroy(pass1_bb);490 heap::c_allocator.destroy(pass1_bb);
791 }491 }
792 ira->old_irb.exec->basic_block_list.deinit();492 ira->zir->basic_block_list.deinit();
793 ira->old_irb.exec->tld_list.deinit();493 ira->zir->tld_list.deinit();
794 heap::c_allocator.destroy(ira->old_irb.exec);494 heap::c_allocator.destroy(ira->zir);
795 ira->src_implicit_return_type_list.deinit();495 ira->src_implicit_return_type_list.deinit();
796 ira->resume_stack.deinit();496 ira->resume_stack.deinit();
797497
...@@ -970,54 +670,18 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte...@@ -970,54 +670,18 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte
970 zig_unreachable();670 zig_unreachable();
971}671}
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
995static void ir_inst_gen_append(IrBasicBlockGen *basic_block, IrInstGen *instruction) {673static void ir_inst_gen_append(IrBasicBlockGen *basic_block, IrInstGen *instruction) {
996 assert(basic_block);674 assert(basic_block);
997 assert(instruction);675 assert(instruction);
998 basic_block->instruction_list.append(instruction);676 basic_block->instruction_list.append(instruction);
999}677}
1000678
1001static size_t exec_next_debug_id(IrExecutableSrc *exec) {679static size_t exec_next_debug_id_gen(Stage1Air *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) {
1008 size_t result = exec->next_debug_id;680 size_t result = exec->next_debug_id;
1009 exec->next_debug_id += 1;681 exec->next_debug_id += 1;
1010 return result;682 return result;
1011}683}
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
1021static bool value_is_comptime(ZigValue *const_val) {685static bool value_is_comptime(ZigValue *const_val) {
1022 return const_val->special != ConstValSpecialRuntime;686 return const_val->special != ConstValSpecialRuntime;
1023}687}
...@@ -1026,33 +690,11 @@ static bool instr_is_comptime(IrInstGen *instruction) {...@@ -1026,33 +690,11 @@ static bool instr_is_comptime(IrInstGen *instruction) {
1026 return value_is_comptime(instruction->value);690 return value_is_comptime(instruction->value);
1027}691}
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
1047static void ir_ref_inst_gen(IrInstGen *instruction) {693static void ir_ref_inst_gen(IrInstGen *instruction) {
1048 assert(instruction->id != IrInstGenIdInvalid);694 assert(instruction->id != IrInstGenIdInvalid);
1049 instruction->base.ref_count += 1;695 instruction->base.ref_count += 1;
1050}696}
1051697
1052static void ir_ref_var(ZigVar *var) {
1053 var->ref_count += 1;
1054}
1055
1056static void create_result_ptr(CodeGen *codegen, ZigType *expected_type,698static void create_result_ptr(CodeGen *codegen, ZigType *expected_type,
1057 ZigValue **out_result, ZigValue **out_result_ptr)699 ZigValue **out_result, ZigValue **out_result_ptr)
1058{700{
...@@ -1078,7 +720,7 @@ ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) {...@@ -1078,7 +720,7 @@ ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) {
1078 create_result_ptr(ira->codegen, ira->codegen->builtin_types.entry_type, &result, &result_ptr);720 create_result_ptr(ira->codegen, ira->codegen->builtin_types.entry_type, &result, &result_ptr);
1079721
1080 if ((err = ir_eval_const_value(ira->codegen, scope, node, result_ptr,722 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,
1082 nullptr, nullptr, node, nullptr, ira->new_irb.exec, nullptr, UndefBad)))724 nullptr, nullptr, node, nullptr, ira->new_irb.exec, nullptr, UndefBad)))
1083 {725 {
1084 return ira->codegen->builtin_types.entry_invalid;726 return ira->codegen->builtin_types.entry_invalid;
...@@ -1092,15 +734,6 @@ ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) {...@@ -1092,15 +734,6 @@ ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) {
1092 return res_type;734 return res_type;
1093}735}
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
1104static IrBasicBlockGen *ir_create_basic_block_gen(IrAnalyze *ira, Scope *scope, const char *name_hint) {737static IrBasicBlockGen *ir_create_basic_block_gen(IrAnalyze *ira, Scope *scope, const char *name_hint) {
1105 IrBasicBlockGen *result = heap::c_allocator.create<IrBasicBlockGen>();738 IrBasicBlockGen *result = heap::c_allocator.create<IrBasicBlockGen>();
1106 result->scope = scope;739 result->scope = scope;
...@@ -1109,8813 +742,1693 @@ static IrBasicBlockGen *ir_create_basic_block_gen(IrAnalyze *ira, Scope *scope,...@@ -1109,8813 +742,1693 @@ static IrBasicBlockGen *ir_create_basic_block_gen(IrAnalyze *ira, Scope *scope,
1109 return result;742 return result;
1110}743}
1111744
1112static IrBasicBlockGen *ir_build_bb_from(IrAnalyze *ira, IrBasicBlockSrc *other_bb) {745static IrBasicBlockGen *ir_build_bb_from(IrAnalyze *ira, Stage1ZirBasicBlock *other_bb) {
1113 IrBasicBlockGen *new_bb = ir_create_basic_block_gen(ira, other_bb->scope, other_bb->name_hint);746 IrBasicBlockGen *new_bb = ir_create_basic_block_gen(ira, other_bb->scope, other_bb->name_hint);
1114 other_bb->child = new_bb;747 other_bb->child = new_bb;
1115 return new_bb;748 return new_bb;
1116}749}
1117750
1118static constexpr IrInstSrcId ir_inst_id(IrInstSrcDeclVar *) {751static constexpr IrInstGenId ir_inst_id(IrInstGenDeclVar *) {
1119 return IrInstSrcIdDeclVar;752 return IrInstGenIdDeclVar;
1120}753}
1121754
1122static constexpr IrInstSrcId ir_inst_id(IrInstSrcBr *) {755static constexpr IrInstGenId ir_inst_id(IrInstGenBr *) {
1123 return IrInstSrcIdBr;756 return IrInstGenIdBr;
1124}757}
1125758
1126static constexpr IrInstSrcId ir_inst_id(IrInstSrcCondBr *) {759static constexpr IrInstGenId ir_inst_id(IrInstGenCondBr *) {
1127 return IrInstSrcIdCondBr;760 return IrInstGenIdCondBr;
1128}761}
1129762
1130static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchBr *) {763static constexpr IrInstGenId ir_inst_id(IrInstGenSwitchBr *) {
1131 return IrInstSrcIdSwitchBr;764 return IrInstGenIdSwitchBr;
1132}765}
1133766
1134static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchVar *) {767static constexpr IrInstGenId ir_inst_id(IrInstGenPhi *) {
1135 return IrInstSrcIdSwitchVar;768 return IrInstGenIdPhi;
1136}769}
1137770
1138static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchElseVar *) {771static constexpr IrInstGenId ir_inst_id(IrInstGenBinaryNot *) {
1139 return IrInstSrcIdSwitchElseVar;772 return IrInstGenIdBinaryNot;
1140}773}
1141774
1142static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchTarget *) {775static constexpr IrInstGenId ir_inst_id(IrInstGenNegation *) {
1143 return IrInstSrcIdSwitchTarget;776 return IrInstGenIdNegation;
1144}777}
1145778
1146static constexpr IrInstSrcId ir_inst_id(IrInstSrcPhi *) {779static constexpr IrInstGenId ir_inst_id(IrInstGenBinOp *) {
1147 return IrInstSrcIdPhi;780 return IrInstGenIdBinOp;
1148}781}
1149782
1150static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnOp *) {783static constexpr IrInstGenId ir_inst_id(IrInstGenLoadPtr *) {
1151 return IrInstSrcIdUnOp;784 return IrInstGenIdLoadPtr;
1152}785}
1153786
1154static constexpr IrInstSrcId ir_inst_id(IrInstSrcBinOp *) {787static constexpr IrInstGenId ir_inst_id(IrInstGenStorePtr *) {
1155 return IrInstSrcIdBinOp;788 return IrInstGenIdStorePtr;
1156}789}
1157790
1158static constexpr IrInstSrcId ir_inst_id(IrInstSrcMergeErrSets *) {791static constexpr IrInstGenId ir_inst_id(IrInstGenVectorStoreElem *) {
1159 return IrInstSrcIdMergeErrSets;792 return IrInstGenIdVectorStoreElem;
1160}793}
1161794
1162static constexpr IrInstSrcId ir_inst_id(IrInstSrcLoadPtr *) {795static constexpr IrInstGenId ir_inst_id(IrInstGenStructFieldPtr *) {
1163 return IrInstSrcIdLoadPtr;796 return IrInstGenIdStructFieldPtr;
1164}797}
1165798
1166static constexpr IrInstSrcId ir_inst_id(IrInstSrcStorePtr *) {799static constexpr IrInstGenId ir_inst_id(IrInstGenUnionFieldPtr *) {
1167 return IrInstSrcIdStorePtr;800 return IrInstGenIdUnionFieldPtr;
1168}801}
1169802
1170static constexpr IrInstSrcId ir_inst_id(IrInstSrcFieldPtr *) {803static constexpr IrInstGenId ir_inst_id(IrInstGenElemPtr *) {
1171 return IrInstSrcIdFieldPtr;804 return IrInstGenIdElemPtr;
1172}805}
1173806
1174static constexpr IrInstSrcId ir_inst_id(IrInstSrcElemPtr *) {807static constexpr IrInstGenId ir_inst_id(IrInstGenVarPtr *) {
1175 return IrInstSrcIdElemPtr;808 return IrInstGenIdVarPtr;
1176}809}
1177810
1178static constexpr IrInstSrcId ir_inst_id(IrInstSrcVarPtr *) {811static constexpr IrInstGenId ir_inst_id(IrInstGenReturnPtr *) {
1179 return IrInstSrcIdVarPtr;812 return IrInstGenIdReturnPtr;
1180}813}
1181814
1182static constexpr IrInstSrcId ir_inst_id(IrInstSrcCall *) {815static constexpr IrInstGenId ir_inst_id(IrInstGenCall *) {
1183 return IrInstSrcIdCall;816 return IrInstGenIdCall;
1184}817}
1185818
1186static constexpr IrInstSrcId ir_inst_id(IrInstSrcCallArgs *) {819static constexpr IrInstGenId ir_inst_id(IrInstGenReturn *) {
1187 return IrInstSrcIdCallArgs;820 return IrInstGenIdReturn;
1188}821}
1189822
1190static constexpr IrInstSrcId ir_inst_id(IrInstSrcCallExtra *) {823static constexpr IrInstGenId ir_inst_id(IrInstGenCast *) {
1191 return IrInstSrcIdCallExtra;824 return IrInstGenIdCast;
1192}825}
1193826
1194static constexpr IrInstSrcId ir_inst_id(IrInstSrcAsyncCallExtra *) {827static constexpr IrInstGenId ir_inst_id(IrInstGenUnreachable *) {
1195 return IrInstSrcIdAsyncCallExtra;828 return IrInstGenIdUnreachable;
1196}829}
1197830
1198static constexpr IrInstSrcId ir_inst_id(IrInstSrcConst *) {831static constexpr IrInstGenId ir_inst_id(IrInstGenAsm *) {
1199 return IrInstSrcIdConst;832 return IrInstGenIdAsm;
1200}833}
1201834
1202static constexpr IrInstSrcId ir_inst_id(IrInstSrcReturn *) {835static constexpr IrInstGenId ir_inst_id(IrInstGenTestNonNull *) {
1203 return IrInstSrcIdReturn;836 return IrInstGenIdTestNonNull;
1204}837}
1205838
1206static constexpr IrInstSrcId ir_inst_id(IrInstSrcContainerInitList *) {839static constexpr IrInstGenId ir_inst_id(IrInstGenOptionalUnwrapPtr *) {
1207 return IrInstSrcIdContainerInitList;840 return IrInstGenIdOptionalUnwrapPtr;
1208}841}
1209842
1210static constexpr IrInstSrcId ir_inst_id(IrInstSrcContainerInitFields *) {843static constexpr IrInstGenId ir_inst_id(IrInstGenOptionalWrap *) {
1211 return IrInstSrcIdContainerInitFields;844 return IrInstGenIdOptionalWrap;
1212}845}
1213846
1214static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnreachable *) {847static constexpr IrInstGenId ir_inst_id(IrInstGenUnionTag *) {
1215 return IrInstSrcIdUnreachable;848 return IrInstGenIdUnionTag;
1216}849}
1217850
1218static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeOf *) {851static constexpr IrInstGenId ir_inst_id(IrInstGenClz *) {
1219 return IrInstSrcIdTypeOf;852 return IrInstGenIdClz;
1220}853}
1221854
1222static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetCold *) {855static constexpr IrInstGenId ir_inst_id(IrInstGenCtz *) {
1223 return IrInstSrcIdSetCold;856 return IrInstGenIdCtz;
1224}857}
1225858
1226static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetRuntimeSafety *) {859static constexpr IrInstGenId ir_inst_id(IrInstGenPopCount *) {
1227 return IrInstSrcIdSetRuntimeSafety;860 return IrInstGenIdPopCount;
1228}861}
1229862
1230static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetFloatMode *) {863static constexpr IrInstGenId ir_inst_id(IrInstGenBswap *) {
1231 return IrInstSrcIdSetFloatMode;864 return IrInstGenIdBswap;
1232}865}
1233866
1234static constexpr IrInstSrcId ir_inst_id(IrInstSrcArrayType *) {867static constexpr IrInstGenId ir_inst_id(IrInstGenBitReverse *) {
1235 return IrInstSrcIdArrayType;868 return IrInstGenIdBitReverse;
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;
1248}869}
1249870
1250static constexpr IrInstSrcId ir_inst_id(IrInstSrcSizeOf *) {871static constexpr IrInstGenId ir_inst_id(IrInstGenRef *) {
1251 return IrInstSrcIdSizeOf;872 return IrInstGenIdRef;
1252}873}
1253874
1254static constexpr IrInstSrcId ir_inst_id(IrInstSrcTestNonNull *) {875static constexpr IrInstGenId ir_inst_id(IrInstGenErrName *) {
1255 return IrInstSrcIdTestNonNull;876 return IrInstGenIdErrName;
1256}877}
1257878
1258static constexpr IrInstSrcId ir_inst_id(IrInstSrcOptionalUnwrapPtr *) {879static constexpr IrInstGenId ir_inst_id(IrInstGenCmpxchg *) {
1259 return IrInstSrcIdOptionalUnwrapPtr;880 return IrInstGenIdCmpxchg;
1260}881}
1261882
1262static constexpr IrInstSrcId ir_inst_id(IrInstSrcClz *) {883static constexpr IrInstGenId ir_inst_id(IrInstGenFence *) {
1263 return IrInstSrcIdClz;884 return IrInstGenIdFence;
1264}885}
1265886
1266static constexpr IrInstSrcId ir_inst_id(IrInstSrcCtz *) {887static constexpr IrInstGenId ir_inst_id(IrInstGenReduce *) {
1267 return IrInstSrcIdCtz;888 return IrInstGenIdReduce;
1268}889}
1269890
1270static constexpr IrInstSrcId ir_inst_id(IrInstSrcPopCount *) {891static constexpr IrInstGenId ir_inst_id(IrInstGenTruncate *) {
1271 return IrInstSrcIdPopCount;892 return IrInstGenIdTruncate;
1272}893}
1273894
1274static constexpr IrInstSrcId ir_inst_id(IrInstSrcBswap *) {895static constexpr IrInstGenId ir_inst_id(IrInstGenShuffleVector *) {
1275 return IrInstSrcIdBswap;896 return IrInstGenIdShuffleVector;
1276}897}
1277898
1278static constexpr IrInstSrcId ir_inst_id(IrInstSrcBitReverse *) {899static constexpr IrInstGenId ir_inst_id(IrInstGenSplat *) {
1279 return IrInstSrcIdBitReverse;900 return IrInstGenIdSplat;
1280}901}
1281902
1282static constexpr IrInstSrcId ir_inst_id(IrInstSrcImport *) {903static constexpr IrInstGenId ir_inst_id(IrInstGenBoolNot *) {
1283 return IrInstSrcIdImport;904 return IrInstGenIdBoolNot;
1284}905}
1285906
1286static constexpr IrInstSrcId ir_inst_id(IrInstSrcCImport *) {907static constexpr IrInstGenId ir_inst_id(IrInstGenMemset *) {
1287 return IrInstSrcIdCImport;908 return IrInstGenIdMemset;
1288}909}
1289910
1290static constexpr IrInstSrcId ir_inst_id(IrInstSrcCInclude *) {911static constexpr IrInstGenId ir_inst_id(IrInstGenMemcpy *) {
1291 return IrInstSrcIdCInclude;912 return IrInstGenIdMemcpy;
1292}913}
1293914
1294static constexpr IrInstSrcId ir_inst_id(IrInstSrcCDefine *) {915static constexpr IrInstGenId ir_inst_id(IrInstGenSlice *) {
1295 return IrInstSrcIdCDefine;916 return IrInstGenIdSlice;
1296}917}
1297918
1298static constexpr IrInstSrcId ir_inst_id(IrInstSrcCUndef *) {919static constexpr IrInstGenId ir_inst_id(IrInstGenBreakpoint *) {
1299 return IrInstSrcIdCUndef;920 return IrInstGenIdBreakpoint;
1300}921}
1301922
1302static constexpr IrInstSrcId ir_inst_id(IrInstSrcRef *) {923static constexpr IrInstGenId ir_inst_id(IrInstGenReturnAddress *) {
1303 return IrInstSrcIdRef;924 return IrInstGenIdReturnAddress;
1304}925}
1305926
1306static constexpr IrInstSrcId ir_inst_id(IrInstSrcCompileErr *) {927static constexpr IrInstGenId ir_inst_id(IrInstGenFrameAddress *) {
1307 return IrInstSrcIdCompileErr;928 return IrInstGenIdFrameAddress;
1308}929}
1309930
1310static constexpr IrInstSrcId ir_inst_id(IrInstSrcCompileLog *) {931static constexpr IrInstGenId ir_inst_id(IrInstGenFrameHandle *) {
1311 return IrInstSrcIdCompileLog;932 return IrInstGenIdFrameHandle;
1312}933}
1313934
1314static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrName *) {935static constexpr IrInstGenId ir_inst_id(IrInstGenFrameSize *) {
1315 return IrInstSrcIdErrName;936 return IrInstGenIdFrameSize;
1316}937}
1317938
1318static constexpr IrInstSrcId ir_inst_id(IrInstSrcEmbedFile *) {939static constexpr IrInstGenId ir_inst_id(IrInstGenOverflowOp *) {
1319 return IrInstSrcIdEmbedFile;940 return IrInstGenIdOverflowOp;
1320}941}
1321942
1322static constexpr IrInstSrcId ir_inst_id(IrInstSrcCmpxchg *) {943static constexpr IrInstGenId ir_inst_id(IrInstGenTestErr *) {
1323 return IrInstSrcIdCmpxchg;944 return IrInstGenIdTestErr;
1324}945}
1325946
1326static constexpr IrInstSrcId ir_inst_id(IrInstSrcFence *) {947static constexpr IrInstGenId ir_inst_id(IrInstGenMulAdd *) {
1327 return IrInstSrcIdFence;948 return IrInstGenIdMulAdd;
1328}949}
1329950
1330static constexpr IrInstSrcId ir_inst_id(IrInstSrcReduce *) {951static constexpr IrInstGenId ir_inst_id(IrInstGenFloatOp *) {
1331 return IrInstSrcIdReduce;952 return IrInstGenIdFloatOp;
1332}953}
1333954
1334static constexpr IrInstSrcId ir_inst_id(IrInstSrcTruncate *) {955static constexpr IrInstGenId ir_inst_id(IrInstGenUnwrapErrCode *) {
1335 return IrInstSrcIdTruncate;956 return IrInstGenIdUnwrapErrCode;
1336}957}
1337958
1338static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntCast *) {959static constexpr IrInstGenId ir_inst_id(IrInstGenUnwrapErrPayload *) {
1339 return IrInstSrcIdIntCast;960 return IrInstGenIdUnwrapErrPayload;
1340}961}
1341962
1342static constexpr IrInstSrcId ir_inst_id(IrInstSrcFloatCast *) {963static constexpr IrInstGenId ir_inst_id(IrInstGenErrWrapCode *) {
1343 return IrInstSrcIdFloatCast;964 return IrInstGenIdErrWrapCode;
1344}965}
1345966
1346static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToFloat *) {967static constexpr IrInstGenId ir_inst_id(IrInstGenErrWrapPayload *) {
1347 return IrInstSrcIdIntToFloat;968 return IrInstGenIdErrWrapPayload;
1348}969}
1349970
1350static constexpr IrInstSrcId ir_inst_id(IrInstSrcFloatToInt *) {971static constexpr IrInstGenId ir_inst_id(IrInstGenPtrCast *) {
1351 return IrInstSrcIdFloatToInt;972 return IrInstGenIdPtrCast;
1352}973}
1353974
1354static constexpr IrInstSrcId ir_inst_id(IrInstSrcBoolToInt *) {975static constexpr IrInstGenId ir_inst_id(IrInstGenBitCast *) {
1355 return IrInstSrcIdBoolToInt;976 return IrInstGenIdBitCast;
1356}977}
1357978
1358static constexpr IrInstSrcId ir_inst_id(IrInstSrcVectorType *) {979static constexpr IrInstGenId ir_inst_id(IrInstGenWidenOrShorten *) {
1359 return IrInstSrcIdVectorType;980 return IrInstGenIdWidenOrShorten;
1360}981}
1361982
1362static constexpr IrInstSrcId ir_inst_id(IrInstSrcShuffleVector *) {983static constexpr IrInstGenId ir_inst_id(IrInstGenIntToPtr *) {
1363 return IrInstSrcIdShuffleVector;984 return IrInstGenIdIntToPtr;
1364}985}
1365986
1366static constexpr IrInstSrcId ir_inst_id(IrInstSrcSplat *) {987static constexpr IrInstGenId ir_inst_id(IrInstGenPtrToInt *) {
1367 return IrInstSrcIdSplat;988 return IrInstGenIdPtrToInt;
1368}989}
1369990
1370static constexpr IrInstSrcId ir_inst_id(IrInstSrcBoolNot *) {991static constexpr IrInstGenId ir_inst_id(IrInstGenIntToEnum *) {
1371 return IrInstSrcIdBoolNot;992 return IrInstGenIdIntToEnum;
1372}993}
1373994
1374static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemset *) {995static constexpr IrInstGenId ir_inst_id(IrInstGenIntToErr *) {
1375 return IrInstSrcIdMemset;996 return IrInstGenIdIntToErr;
1376}997}
1377998
1378static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemcpy *) {999static constexpr IrInstGenId ir_inst_id(IrInstGenErrToInt *) {
1379 return IrInstSrcIdMemcpy;1000 return IrInstGenIdErrToInt;
1380}1001}
13811002
1382static constexpr IrInstSrcId ir_inst_id(IrInstSrcSlice *) {1003static constexpr IrInstGenId ir_inst_id(IrInstGenPanic *) {
1383 return IrInstSrcIdSlice;1004 return IrInstGenIdPanic;
1384}1005}
13851006
1386static constexpr IrInstSrcId ir_inst_id(IrInstSrcBreakpoint *) {1007static constexpr IrInstGenId ir_inst_id(IrInstGenTagName *) {
1387 return IrInstSrcIdBreakpoint;1008 return IrInstGenIdTagName;
1388}1009}
13891010
1390static constexpr IrInstSrcId ir_inst_id(IrInstSrcReturnAddress *) {1011static constexpr IrInstGenId ir_inst_id(IrInstGenFieldParentPtr *) {
1391 return IrInstSrcIdReturnAddress;1012 return IrInstGenIdFieldParentPtr;
1392}1013}
13931014
1394static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameAddress *) {1015static constexpr IrInstGenId ir_inst_id(IrInstGenAlignCast *) {
1395 return IrInstSrcIdFrameAddress;1016 return IrInstGenIdAlignCast;
1396}1017}
13971018
1398static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameHandle *) {1019static constexpr IrInstGenId ir_inst_id(IrInstGenErrorReturnTrace *) {
1399 return IrInstSrcIdFrameHandle;1020 return IrInstGenIdErrorReturnTrace;
1400}1021}
14011022
1402static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameType *) {1023static constexpr IrInstGenId ir_inst_id(IrInstGenAtomicRmw *) {
1403 return IrInstSrcIdFrameType;1024 return IrInstGenIdAtomicRmw;
1404}1025}
14051026
1406static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameSize *) {1027static constexpr IrInstGenId ir_inst_id(IrInstGenAtomicLoad *) {
1407 return IrInstSrcIdFrameSize;1028 return IrInstGenIdAtomicLoad;
1408}1029}
14091030
1410static constexpr IrInstSrcId ir_inst_id(IrInstSrcAlignOf *) {1031static constexpr IrInstGenId ir_inst_id(IrInstGenAtomicStore *) {
1411 return IrInstSrcIdAlignOf;1032 return IrInstGenIdAtomicStore;
1412}1033}
14131034
1414static constexpr IrInstSrcId ir_inst_id(IrInstSrcOverflowOp *) {1035static constexpr IrInstGenId ir_inst_id(IrInstGenSaveErrRetAddr *) {
1415 return IrInstSrcIdOverflowOp;1036 return IrInstGenIdSaveErrRetAddr;
1416}1037}
14171038
1418static constexpr IrInstSrcId ir_inst_id(IrInstSrcTestErr *) {1039static constexpr IrInstGenId ir_inst_id(IrInstGenVectorToArray *) {
1419 return IrInstSrcIdTestErr;1040 return IrInstGenIdVectorToArray;
1420}1041}
14211042
1422static constexpr IrInstSrcId ir_inst_id(IrInstSrcMulAdd *) {1043static constexpr IrInstGenId ir_inst_id(IrInstGenArrayToVector *) {
1423 return IrInstSrcIdMulAdd;1044 return IrInstGenIdArrayToVector;
1424}1045}
14251046
1426static constexpr IrInstSrcId ir_inst_id(IrInstSrcFloatOp *) {1047static constexpr IrInstGenId ir_inst_id(IrInstGenAssertZero *) {
1427 return IrInstSrcIdFloatOp;1048 return IrInstGenIdAssertZero;
1428}1049}
14291050
1430static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnwrapErrCode *) {1051static constexpr IrInstGenId ir_inst_id(IrInstGenAssertNonNull *) {
1431 return IrInstSrcIdUnwrapErrCode;1052 return IrInstGenIdAssertNonNull;
1432}1053}
14331054
1434static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnwrapErrPayload *) {1055static constexpr IrInstGenId ir_inst_id(IrInstGenPtrOfArrayToSlice *) {
1435 return IrInstSrcIdUnwrapErrPayload;1056 return IrInstGenIdPtrOfArrayToSlice;
1436}1057}
14371058
1438static constexpr IrInstSrcId ir_inst_id(IrInstSrcFnProto *) {1059static constexpr IrInstGenId ir_inst_id(IrInstGenSuspendBegin *) {
1439 return IrInstSrcIdFnProto;1060 return IrInstGenIdSuspendBegin;
1440}1061}
14411062
1442static constexpr IrInstSrcId ir_inst_id(IrInstSrcTestComptime *) {1063static constexpr IrInstGenId ir_inst_id(IrInstGenSuspendFinish *) {
1443 return IrInstSrcIdTestComptime;1064 return IrInstGenIdSuspendFinish;
1444}1065}
14451066
1446static constexpr IrInstSrcId ir_inst_id(IrInstSrcPtrCast *) {1067static constexpr IrInstGenId ir_inst_id(IrInstGenAwait *) {
1447 return IrInstSrcIdPtrCast;1068 return IrInstGenIdAwait;
1448}1069}
14491070
1450static constexpr IrInstSrcId ir_inst_id(IrInstSrcBitCast *) {1071static constexpr IrInstGenId ir_inst_id(IrInstGenResume *) {
1451 return IrInstSrcIdBitCast;1072 return IrInstGenIdResume;
1452}1073}
14531074
1454static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToPtr *) {1075static constexpr IrInstGenId ir_inst_id(IrInstGenSpillBegin *) {
1455 return IrInstSrcIdIntToPtr;1076 return IrInstGenIdSpillBegin;
1456}1077}
14571078
1458static constexpr IrInstSrcId ir_inst_id(IrInstSrcPtrToInt *) {1079static constexpr IrInstGenId ir_inst_id(IrInstGenSpillEnd *) {
1459 return IrInstSrcIdPtrToInt;1080 return IrInstGenIdSpillEnd;
1460}1081}
14611082
1462static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToEnum *) {1083static constexpr IrInstGenId ir_inst_id(IrInstGenVectorExtractElem *) {
1463 return IrInstSrcIdIntToEnum;1084 return IrInstGenIdVectorExtractElem;
1464}1085}
14651086
1466static constexpr IrInstSrcId ir_inst_id(IrInstSrcEnumToInt *) {1087static constexpr IrInstGenId ir_inst_id(IrInstGenAlloca *) {
1467 return IrInstSrcIdEnumToInt;1088 return IrInstGenIdAlloca;
1468}1089}
14691090
1470static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToErr *) {1091static constexpr IrInstGenId ir_inst_id(IrInstGenConst *) {
1471 return IrInstSrcIdIntToErr;1092 return IrInstGenIdConst;
1472}1093}
14731094
1474static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrToInt *) {1095static constexpr IrInstGenId ir_inst_id(IrInstGenWasmMemorySize *) {
1475 return IrInstSrcIdErrToInt;1096 return IrInstGenIdWasmMemorySize;
1476}1097}
14771098
1478static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckStatementIsVoid *) {1099static constexpr IrInstGenId ir_inst_id(IrInstGenWasmMemoryGrow *) {
1479 return IrInstSrcIdCheckStatementIsVoid;1100 return IrInstGenIdWasmMemoryGrow;
1480}1101}
14811102
1482static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeName *) {1103static constexpr IrInstGenId ir_inst_id(IrInstGenExtern *) {
1483 return IrInstSrcIdTypeName;1104 return IrInstGenIdExtern;
1484}1105}
14851106
1486static constexpr IrInstSrcId ir_inst_id(IrInstSrcDeclRef *) {1107template<typename T>
1487 return IrInstSrcIdDeclRef;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;
1488}1117}
14891118
1490static constexpr IrInstSrcId ir_inst_id(IrInstSrcPanic *) {1119template<typename T>
1491 return IrInstSrcIdPanic;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;
1492}1128}
14931129
1494static constexpr IrInstSrcId ir_inst_id(IrInstSrcTagName *) {1130template<typename T>
1495 return IrInstSrcIdTagName;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;
1496}1135}
14971136
1498static constexpr IrInstSrcId ir_inst_id(IrInstSrcFieldParentPtr *) {1137template<typename T>
1499 return IrInstSrcIdFieldParentPtr;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;
1500}1143}
15011144
1502static constexpr IrInstSrcId ir_inst_id(IrInstSrcByteOffsetOf *) {1145template<typename T>
1503 return IrInstSrcIdByteOffsetOf;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;
1504}1151}
15051152
1506static constexpr IrInstSrcId ir_inst_id(IrInstSrcBitOffsetOf *) {1153IrInstGen *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node, ZigFn *fn,
1507 return IrInstSrcIdBitOffsetOf;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;
1508}1166}
15091167
1510static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeInfo *) {1168static IrInstGen *ir_build_cast(IrAnalyze *ira, IrInst *source_instr,ZigType *dest_type,
1511 return IrInstSrcIdTypeInfo;1169 IrInstGen *value, CastOp cast_op)
1512}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 *) {1176 ir_ref_inst_gen(value);
1515 return IrInstSrcIdType;
1516}
15171177
1518static constexpr IrInstSrcId ir_inst_id(IrInstSrcHasField *) {1178 return &inst->base;
1519 return IrInstSrcIdHasField;
1520}1179}
15211180
1522static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetEvalBranchQuota *) {1181static IrInstGen *ir_build_cond_br_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *condition,
1523 return IrInstSrcIdSetEvalBranchQuota;1182 IrBasicBlockGen *then_block, IrBasicBlockGen *else_block)
1524}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 *) {1189 ir_ref_inst_gen(condition);
1527 return IrInstSrcIdPtrType;
1528}
15291190
1530static constexpr IrInstSrcId ir_inst_id(IrInstSrcAlignCast *) {1191 return &inst->base;
1531 return IrInstSrcIdAlignCast;
1532}1192}
15331193
1534static constexpr IrInstSrcId ir_inst_id(IrInstSrcImplicitCast *) {1194static IrInstGen *ir_build_return_gen(IrAnalyze *ira, IrInst *source_inst, IrInstGen *operand) {
1535 return IrInstSrcIdImplicitCast;1195 IrInstGenReturn *inst = ir_build_inst_noreturn<IrInstGenReturn>(&ira->new_irb,
1536}1196 source_inst->scope, source_inst->source_node);
1197 inst->operand = operand;
15371198
1538static constexpr IrInstSrcId ir_inst_id(IrInstSrcResolveResult *) {1199 if (operand != nullptr) ir_ref_inst_gen(operand);
1539 return IrInstSrcIdResolveResult;
1540}
15411200
1542static constexpr IrInstSrcId ir_inst_id(IrInstSrcResetResult *) {1201 return &inst->base;
1543 return IrInstSrcIdResetResult;
1544}1202}
15451203
1546static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetAlignStack *) {1204static IrInstGen *ir_build_bin_op_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *res_type,
1547 return IrInstSrcIdSetAlignStack;1205 IrBinOp op_id, IrInstGen *op1, IrInstGen *op2, bool safety_check_on)
1548}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 *) {1215 ir_ref_inst_gen(op1);
1551 return IrInstSrcIdExport;1216 ir_ref_inst_gen(op2);
1552}
15531217
1554static constexpr IrInstSrcId ir_inst_id(IrInstSrcExtern *) {1218 return &inst->base;
1555 return IrInstSrcIdExtern;
1556}1219}
15571220
1558static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrorReturnTrace *) {
1559 return IrInstSrcIdErrorReturnTrace;
1560}
15611221
1562static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrorUnion *) {1222static IrInstGen *ir_build_var_ptr_gen(IrAnalyze *ira, IrInst *source_instr, ZigVar *var) {
1563 return IrInstSrcIdErrorUnion;1223 IrInstGenVarPtr *instruction = ir_build_inst_gen<IrInstGenVarPtr>(&ira->new_irb, source_instr->scope, source_instr->source_node);
1564}1224 instruction->var = var;
15651225
1566static constexpr IrInstSrcId ir_inst_id(IrInstSrcAtomicRmw *) {1226 var->ref_count += 1;
1567 return IrInstSrcIdAtomicRmw;
1568}
15691227
1570static constexpr IrInstSrcId ir_inst_id(IrInstSrcAtomicLoad *) {1228 return &instruction->base;
1571 return IrInstSrcIdAtomicLoad;
1572}1229}
15731230
1574static constexpr IrInstSrcId ir_inst_id(IrInstSrcAtomicStore *) {1231static IrInstGen *ir_build_return_ptr(IrAnalyze *ira, Scope *scope, AstNode *source_node, ZigType *ty) {
1575 return IrInstSrcIdAtomicStore;1232 IrInstGenReturnPtr *instruction = ir_build_inst_gen<IrInstGenReturnPtr>(&ira->new_irb, scope, source_node);
1233 instruction->base.value->type = ty;
1234 return &instruction->base;
1576}1235}
15771236
1578static constexpr IrInstSrcId ir_inst_id(IrInstSrcSaveErrRetAddr *) {1237static IrInstGen *ir_build_elem_ptr_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node,
1579 return IrInstSrcIdSaveErrRetAddr;1238 IrInstGen *array_ptr, IrInstGen *elem_index, bool safety_check_on, ZigType *return_type)
1580}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 *) {1246 ir_ref_inst_gen(array_ptr);
1583 return IrInstSrcIdAddImplicitReturnType;1247 ir_ref_inst_gen(elem_index);
1584}
15851248
1586static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrSetCast *) {1249 return &instruction->base;
1587 return IrInstSrcIdErrSetCast;
1588}1250}
15891251
1590static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckRuntimeScope *) {1252static IrInstGen *ir_build_struct_field_ptr(IrAnalyze *ira, IrInst *source_instr,
1591 return IrInstSrcIdCheckRuntimeScope;1253 IrInstGen *struct_ptr, TypeStructField *field, ZigType *ptr_type)
1592}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 *) {1260 ir_ref_inst_gen(struct_ptr);
1595 return IrInstSrcIdHasDecl;
1596}
15971261
1598static constexpr IrInstSrcId ir_inst_id(IrInstSrcUndeclaredIdent *) {1262 return &inst->base;
1599 return IrInstSrcIdUndeclaredIdent;
1600}1263}
16011264
1602static constexpr IrInstSrcId ir_inst_id(IrInstSrcAlloca *) {1265static IrInstGen *ir_build_union_field_ptr(IrAnalyze *ira, IrInst *source_instr,
1603 return IrInstSrcIdAlloca;1266 IrInstGen *union_ptr, TypeUnionField *field, bool safety_check_on, bool initializing, ZigType *ptr_type)
1604}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 *) {1276 ir_ref_inst_gen(union_ptr);
1607 return IrInstSrcIdEndExpr;
1608}
16091277
1610static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnionInitNamedField *) {1278 return &inst->base;
1611 return IrInstSrcIdUnionInitNamedField;
1612}1279}
16131280
1614static constexpr IrInstSrcId ir_inst_id(IrInstSrcSuspendBegin *) {1281static IrInstGenCall *ir_build_call_gen(IrAnalyze *ira, IrInst *source_instruction,
1615 return IrInstSrcIdSuspendBegin;1282 ZigFn *fn_entry, IrInstGen *fn_ref, size_t arg_count, IrInstGen **args,
1616}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 *) {1298 if (fn_ref != nullptr) ir_ref_inst_gen(fn_ref);
1619 return IrInstSrcIdSuspendFinish;1299 for (size_t i = 0; i < arg_count; i += 1)
1620}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 *) {1304 return call_instruction;
1623 return IrInstSrcIdAwait;
1624}1305}
16251306
1626static constexpr IrInstSrcId ir_inst_id(IrInstSrcResume *) {1307static IrInstGen *ir_build_phi_gen(IrAnalyze *ira, IrInst *source_instr, size_t incoming_count,
1627 return IrInstSrcIdResume;1308 IrBasicBlockGen **incoming_blocks, IrInstGen **incoming_values, ZigType *result_type)
1628}1309{
1310 assert(incoming_count != 0);
1311 assert(incoming_count != SIZE_MAX);
16291312
1630static constexpr IrInstSrcId ir_inst_id(IrInstSrcSpillBegin *) {1313 IrInstGenPhi *phi_instruction = ir_build_inst_gen<IrInstGenPhi>(&ira->new_irb,
1631 return IrInstSrcIdSpillBegin;1314 source_instr->scope, source_instr->source_node);
1632}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 *) {1320 for (size_t i = 0; i < incoming_count; i += 1) {
1635 return IrInstSrcIdSpillEnd;1321 ir_ref_inst_gen(incoming_values[i]);
1636}1322 }
16371323
1638static constexpr IrInstSrcId ir_inst_id(IrInstSrcWasmMemorySize *) {1324 return &phi_instruction->base;
1639 return IrInstSrcIdWasmMemorySize;
1640}1325}
16411326
1642static constexpr IrInstSrcId ir_inst_id(IrInstSrcWasmMemoryGrow *) {1327static IrInstGen *ir_build_br_gen(IrAnalyze *ira, IrInst *source_instr, IrBasicBlockGen *dest_block) {
1643 return IrInstSrcIdWasmMemoryGrow;1328 IrInstGenBr *inst = ir_build_inst_noreturn<IrInstGenBr>(&ira->new_irb, source_instr->scope, source_instr->source_node);
1644}1329 inst->dest_block = dest_block;
16451330
1646static constexpr IrInstSrcId ir_inst_id(IrInstSrcSrc *) {1331 return &inst->base;
1647 return IrInstSrcIdSrc;
1648}1332}
16491333
1650static constexpr IrInstGenId ir_inst_id(IrInstGenDeclVar *) {1334static IrInstGen *ir_build_negation(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, ZigType *expr_type, bool wrapping) {
1651 return IrInstGenIdDeclVar;1335 IrInstGenNegation *instruction = ir_build_inst_gen<IrInstGenNegation>(&ira->new_irb,
1652}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 *) {1341 ir_ref_inst_gen(operand);
1655 return IrInstGenIdBr;
1656}
16571342
1658static constexpr IrInstGenId ir_inst_id(IrInstGenCondBr *) {1343 return &instruction->base;
1659 return IrInstGenIdCondBr;
1660}1344}
16611345
1662static constexpr IrInstGenId ir_inst_id(IrInstGenSwitchBr *) {1346static IrInstGen *ir_build_binary_not(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand,
1663 return IrInstGenIdSwitchBr;1347 ZigType *expr_type)
1664}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 *) {1354 ir_ref_inst_gen(operand);
1667 return IrInstGenIdPhi;
1668}
16691355
1670static constexpr IrInstGenId ir_inst_id(IrInstGenBinaryNot *) {1356 return &instruction->base;
1671 return IrInstGenIdBinaryNot;
1672}1357}
16731358
1674static constexpr IrInstGenId ir_inst_id(IrInstGenNegation *) {1359static IrInstGen *ir_build_unreachable_gen(IrAnalyze *ira, IrInst *source_instr) {
1675 return IrInstGenIdNegation;1360 IrInstGenUnreachable *inst = ir_build_inst_noreturn<IrInstGenUnreachable>(&ira->new_irb, source_instr->scope, source_instr->source_node);
1361 return &inst->base;
1676}1362}
16771363
1678static constexpr IrInstGenId ir_inst_id(IrInstGenBinOp *) {1364static IrInstGen *ir_build_store_ptr_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *ptr, IrInstGen *value) {
1679 return IrInstGenIdBinOp;1365 IrInstGenStorePtr *instruction = ir_build_inst_void<IrInstGenStorePtr>(&ira->new_irb,
1680}1366 source_instr->scope, source_instr->source_node);
1367 instruction->ptr = ptr;
1368 instruction->value = value;
16811369
1682static constexpr IrInstGenId ir_inst_id(IrInstGenLoadPtr *) {1370 ir_ref_inst_gen(ptr);
1683 return IrInstGenIdLoadPtr;1371 ir_ref_inst_gen(value);
1684}
16851372
1686static constexpr IrInstGenId ir_inst_id(IrInstGenStorePtr *) {1373 return &instruction->base;
1687 return IrInstGenIdStorePtr;
1688}1374}
16891375
1690static constexpr IrInstGenId ir_inst_id(IrInstGenVectorStoreElem *) {1376static IrInstGen *ir_build_vector_store_elem(IrAnalyze *ira, IrInst *src_inst,
1691 return IrInstGenIdVectorStoreElem;1377 IrInstGen *vector_ptr, IrInstGen *index, IrInstGen *value)
1692}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 *) {1385 ir_ref_inst_gen(vector_ptr);
1695 return IrInstGenIdStructFieldPtr;1386 ir_ref_inst_gen(index);
1696}1387 ir_ref_inst_gen(value);
16971388
1698static constexpr IrInstGenId ir_inst_id(IrInstGenUnionFieldPtr *) {1389 return &inst->base;
1699 return IrInstGenIdUnionFieldPtr;
1700}1390}
17011391
1702static constexpr IrInstGenId ir_inst_id(IrInstGenElemPtr *) {1392static IrInstGen *ir_build_var_decl_gen(IrAnalyze *ira, IrInst *source_instruction,
1703 return IrInstGenIdElemPtr;1393 ZigVar *var, IrInstGen *var_ptr)
1704}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 *) {1402 ir_ref_inst_gen(var_ptr);
1707 return IrInstGenIdVarPtr;
1708}
17091403
1710static constexpr IrInstGenId ir_inst_id(IrInstGenReturnPtr *) {1404 return &inst->base;
1711 return IrInstGenIdReturnPtr;
1712}1405}
17131406
1714static constexpr IrInstGenId ir_inst_id(IrInstGenCall *) {1407static IrInstGen *ir_build_extern_gen(IrAnalyze *ira, IrInst *source_instr, Buf *name,
1715 return IrInstGenIdCall;1408 GlobalLinkageId linkage, bool is_thread_local, ZigType *expr_type)
1716}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 *) {1417 return &instruction->base;
1719 return IrInstGenIdReturn;
1720}1418}
17211419
1722static constexpr IrInstGenId ir_inst_id(IrInstGenCast *) {1420static IrInstGen *ir_build_load_ptr_gen(IrAnalyze *ira, IrInst *source_instruction,
1723 return IrInstGenIdCast;1421 IrInstGen *ptr, ZigType *ty, IrInstGen *result_loc)
1724}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 *) {1429 ir_ref_inst_gen(ptr);
1727 return IrInstGenIdUnreachable;1430 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
1728}
17291431
1730static constexpr IrInstGenId ir_inst_id(IrInstGenAsm *) {1432 return &instruction->base;
1731 return IrInstGenIdAsm;
1732}1433}
17331434
1734static constexpr IrInstGenId ir_inst_id(IrInstGenTestNonNull *) {1435static IrInstGen *ir_build_asm_gen(IrAnalyze *ira, IrInst *source_instr,
1735 return IrInstGenIdTestNonNull;1436 Buf *asm_template, AsmToken *token_list, size_t token_list_len,
1736}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 *) {1451 assert(source_instr->source_node->type == NodeTypeAsmExpr);
1739 return IrInstGenIdOptionalUnwrapPtr;1452 for (size_t i = 0; i < source_instr->source_node->data.asm_expr.output_list.length; i += 1) {
1740}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 *) {1457 for (size_t i = 0; i < source_instr->source_node->data.asm_expr.input_list.length; i += 1) {
1743 return IrInstGenIdOptionalWrap;1458 IrInstGen *input_value = input_list[i];
1744}1459 ir_ref_inst_gen(input_value);
1460 }
17451461
1746static constexpr IrInstGenId ir_inst_id(IrInstGenUnionTag *) {1462 return &instruction->base;
1747 return IrInstGenIdUnionTag;
1748}1463}
17491464
1750static constexpr IrInstGenId ir_inst_id(IrInstGenClz *) {1465static IrInstGen *ir_build_test_non_null_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value) {
1751 return IrInstGenIdClz;1466 IrInstGenTestNonNull *inst = ir_build_inst_gen<IrInstGenTestNonNull>(&ira->new_irb,
1752}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 *) {1471 ir_ref_inst_gen(value);
1755 return IrInstGenIdCtz;
1756}
17571472
1758static constexpr IrInstGenId ir_inst_id(IrInstGenPopCount *) {1473 return &inst->base;
1759 return IrInstGenIdPopCount;
1760}1474}
17611475
1762static constexpr IrInstGenId ir_inst_id(IrInstGenBswap *) {1476static IrInstGen *ir_build_optional_unwrap_ptr_gen(IrAnalyze *ira, IrInst *source_instr,
1763 return IrInstGenIdBswap;1477 IrInstGen *base_ptr, bool safety_check_on, bool initializing, ZigType *result_type)
1764}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 *) {1486 ir_ref_inst_gen(base_ptr);
1767 return IrInstGenIdBitReverse;1487
1488 return &inst->base;
1768}1489}
17691490
1770static constexpr IrInstGenId ir_inst_id(IrInstGenRef *) {1491static IrInstGen *ir_build_optional_wrap(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_ty,
1771 return IrInstGenIdRef;1492 IrInstGen *operand, IrInstGen *result_loc)
1772}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 *) {1500 ir_ref_inst_gen(operand);
1775 return IrInstGenIdErrName;1501 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
1776}
17771502
1778static constexpr IrInstGenId ir_inst_id(IrInstGenCmpxchg *) {1503 return &instruction->base;
1779 return IrInstGenIdCmpxchg;
1780}1504}
17811505
1782static constexpr IrInstGenId ir_inst_id(IrInstGenFence *) {1506static IrInstGen *ir_build_err_wrap_payload(IrAnalyze *ira, IrInst *source_instruction,
1783 return IrInstGenIdFence;1507 ZigType *result_type, IrInstGen *operand, IrInstGen *result_loc)
1784}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 *) {1515 ir_ref_inst_gen(operand);
1787 return IrInstGenIdReduce;1516 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
1788}
17891517
1790static constexpr IrInstGenId ir_inst_id(IrInstGenTruncate *) {1518 return &instruction->base;
1791 return IrInstGenIdTruncate;
1792}1519}
17931520
1794static constexpr IrInstGenId ir_inst_id(IrInstGenShuffleVector *) {1521static IrInstGen *ir_build_err_wrap_code(IrAnalyze *ira, IrInst *source_instruction,
1795 return IrInstGenIdShuffleVector;1522 ZigType *result_type, IrInstGen *operand, IrInstGen *result_loc)
1796}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 *) {1530 ir_ref_inst_gen(operand);
1799 return IrInstGenIdSplat;1531 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
1800}
18011532
1802static constexpr IrInstGenId ir_inst_id(IrInstGenBoolNot *) {1533 return &instruction->base;
1803 return IrInstGenIdBoolNot;
1804}1534}
18051535
1806static constexpr IrInstGenId ir_inst_id(IrInstGenMemset *) {1536static IrInstGen *ir_build_clz_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *result_type, IrInstGen *op) {
1807 return IrInstGenIdMemset;1537 IrInstGenClz *instruction = ir_build_inst_gen<IrInstGenClz>(&ira->new_irb,
1808}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 *) {1542 ir_ref_inst_gen(op);
1811 return IrInstGenIdMemcpy;
1812}
18131543
1814static constexpr IrInstGenId ir_inst_id(IrInstGenSlice *) {1544 return &instruction->base;
1815 return IrInstGenIdSlice;
1816}1545}
18171546
1818static constexpr IrInstGenId ir_inst_id(IrInstGenBreakpoint *) {1547static IrInstGen *ir_build_ctz_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *result_type, IrInstGen *op) {
1819 return IrInstGenIdBreakpoint;1548 IrInstGenCtz *instruction = ir_build_inst_gen<IrInstGenCtz>(&ira->new_irb,
1820}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 *) {1553 ir_ref_inst_gen(op);
1823 return IrInstGenIdReturnAddress;
1824}
18251554
1826static constexpr IrInstGenId ir_inst_id(IrInstGenFrameAddress *) {1555 return &instruction->base;
1827 return IrInstGenIdFrameAddress;
1828}1556}
18291557
1830static constexpr IrInstGenId ir_inst_id(IrInstGenFrameHandle *) {1558static IrInstGen *ir_build_pop_count_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *result_type,
1831 return IrInstGenIdFrameHandle;1559 IrInstGen *op)
1832}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 *) {1566 ir_ref_inst_gen(op);
1835 return IrInstGenIdFrameSize;
1836}
18371567
1838static constexpr IrInstGenId ir_inst_id(IrInstGenOverflowOp *) {1568 return &instruction->base;
1839 return IrInstGenIdOverflowOp;
1840}1569}
18411570
1842static constexpr IrInstGenId ir_inst_id(IrInstGenTestErr *) {1571static IrInstGen *ir_build_bswap_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *op_type,
1843 return IrInstGenIdTestErr;1572 IrInstGen *op)
1844}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 *) {1579 ir_ref_inst_gen(op);
1847 return IrInstGenIdMulAdd;
1848}
18491580
1850static constexpr IrInstGenId ir_inst_id(IrInstGenFloatOp *) {1581 return &instruction->base;
1851 return IrInstGenIdFloatOp;
1852}1582}
18531583
1854static constexpr IrInstGenId ir_inst_id(IrInstGenUnwrapErrCode *) {1584static IrInstGen *ir_build_bit_reverse_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *int_type,
1855 return IrInstGenIdUnwrapErrCode;1585 IrInstGen *op)
1856}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 *) {1592 ir_ref_inst_gen(op);
1859 return IrInstGenIdUnwrapErrPayload;
1860}
18611593
1862static constexpr IrInstGenId ir_inst_id(IrInstGenErrWrapCode *) {1594 return &instruction->base;
1863 return IrInstGenIdErrWrapCode;
1864}1595}
18651596
1866static constexpr IrInstGenId ir_inst_id(IrInstGenErrWrapPayload *) {1597static IrInstGenSwitchBr *ir_build_switch_br_gen(IrAnalyze *ira, IrInst *source_instr,
1867 return IrInstGenIdErrWrapPayload;1598 IrInstGen *target_value, IrBasicBlockGen *else_block, size_t case_count, IrInstGenSwitchBrCase *cases)
1868}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 *) {1607 ir_ref_inst_gen(target_value);
1871 return IrInstGenIdPtrCast;
1872}
18731608
1874static constexpr IrInstGenId ir_inst_id(IrInstGenBitCast *) {1609 for (size_t i = 0; i < case_count; i += 1) {
1875 return IrInstGenIdBitCast;1610 ir_ref_inst_gen(cases[i].value);
1876}1611 }
18771612
1878static constexpr IrInstGenId ir_inst_id(IrInstGenWidenOrShorten *) {1613 return instruction;
1879 return IrInstGenIdWidenOrShorten;
1880}1614}
18811615
1882static constexpr IrInstGenId ir_inst_id(IrInstGenIntToPtr *) {1616static IrInstGen *ir_build_union_tag(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value,
1883 return IrInstGenIdIntToPtr;1617 ZigType *tag_type)
1884}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 *) {1624 ir_ref_inst_gen(value);
1887 return IrInstGenIdPtrToInt;
1888}
18891625
1890static constexpr IrInstGenId ir_inst_id(IrInstGenIntToEnum *) {1626 return &instruction->base;
1891 return IrInstGenIdIntToEnum;
1892}1627}
18931628
1894static constexpr IrInstGenId ir_inst_id(IrInstGenIntToErr *) {1629static IrInstGen *ir_build_ref_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type,
1895 return IrInstGenIdIntToErr;1630 IrInstGen *operand, IrInstGen *result_loc)
1896}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 *) {1638 ir_ref_inst_gen(operand);
1899 return IrInstGenIdErrToInt;1639 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
1900}
19011640
1902static constexpr IrInstGenId ir_inst_id(IrInstGenPanic *) {1641 return &instruction->base;
1903 return IrInstGenIdPanic;
1904}1642}
19051643
1906static constexpr IrInstGenId ir_inst_id(IrInstGenTagName *) {1644static IrInstGen *ir_build_err_name_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value,
1907 return IrInstGenIdTagName;1645 ZigType *str_type)
1908}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 *) {1652 ir_ref_inst_gen(value);
1911 return IrInstGenIdFieldParentPtr;
1912}
19131653
1914static constexpr IrInstGenId ir_inst_id(IrInstGenAlignCast *) {1654 return &instruction->base;
1915 return IrInstGenIdAlignCast;
1916}1655}
19171656
1918static constexpr IrInstGenId ir_inst_id(IrInstGenErrorReturnTrace *) {1657static IrInstGen *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type,
1919 return IrInstGenIdErrorReturnTrace;1658 IrInstGen *ptr, IrInstGen *cmp_value, IrInstGen *new_value,
1920}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 *) {1672 ir_ref_inst_gen(ptr);
1923 return IrInstGenIdAtomicRmw;1673 ir_ref_inst_gen(cmp_value);
1924}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 *) {1677 return &instruction->base;
1927 return IrInstGenIdAtomicLoad;
1928}1678}
19291679
1930static constexpr IrInstGenId ir_inst_id(IrInstGenAtomicStore *) {1680static IrInstGen *ir_build_fence_gen(IrAnalyze *ira, IrInst *source_instr, AtomicOrder order) {
1931 return IrInstGenIdAtomicStore;1681 IrInstGenFence *instruction = ir_build_inst_void<IrInstGenFence>(&ira->new_irb,
1932}1682 source_instr->scope, source_instr->source_node);
1683 instruction->order = order;
19331684
1934static constexpr IrInstGenId ir_inst_id(IrInstGenSaveErrRetAddr *) {1685 return &instruction->base;
1935 return IrInstGenIdSaveErrRetAddr;
1936}1686}
19371687
1938static constexpr IrInstGenId ir_inst_id(IrInstGenVectorToArray *) {1688static IrInstGen *ir_build_reduce_gen(IrAnalyze *ira, IrInst *source_instruction, ReduceOp op, IrInstGen *value, ZigType *result_type) {
1939 return IrInstGenIdVectorToArray;1689 IrInstGenReduce *instruction = ir_build_inst_gen<IrInstGenReduce>(&ira->new_irb,
1940}1690 source_instruction->scope, source_instruction->source_node);
19411691 instruction->base.value->type = result_type;
1942static constexpr IrInstGenId ir_inst_id(IrInstGenArrayToVector *) {1692 instruction->op = op;
1943 return IrInstGenIdArrayToVector;1693 instruction->value = value;
1944}
19451694
1946static constexpr IrInstGenId ir_inst_id(IrInstGenAssertZero *) {1695 ir_ref_inst_gen(value);
1947 return IrInstGenIdAssertZero;
1948}
19491696
1950static constexpr IrInstGenId ir_inst_id(IrInstGenAssertNonNull *) {1697 return &instruction->base;
1951 return IrInstGenIdAssertNonNull;
1952}1698}
19531699
1954static constexpr IrInstGenId ir_inst_id(IrInstGenPtrOfArrayToSlice *) {1700static void ir_set_cursor_at_end_gen(IrBuilderGen *irb, IrBasicBlockGen *basic_block) {
1955 return IrInstGenIdPtrOfArrayToSlice;1701 assert(basic_block);
1702 irb->current_basic_block = basic_block;
1956}1703}
19571704
1958static constexpr IrInstGenId ir_inst_id(IrInstGenSuspendBegin *) {1705static void ir_append_basic_block_gen(IrBuilderGen *irb, IrBasicBlockGen *bb) {
1959 return IrInstGenIdSuspendBegin;1706 assert(!bb->already_appended);
1707 bb->already_appended = true;
1708 irb->exec->basic_block_list.append(bb);
1960}1709}
19611710
1962static constexpr IrInstGenId ir_inst_id(IrInstGenSuspendFinish *) {1711static void ir_set_cursor_at_end_and_append_block_gen(IrBuilderGen *irb, IrBasicBlockGen *basic_block) {
1963 return IrInstGenIdSuspendFinish;1712 ir_append_basic_block_gen(irb, basic_block);
1713 ir_set_cursor_at_end_gen(irb, basic_block);
1964}1714}
19651715
1966static constexpr IrInstGenId ir_inst_id(IrInstGenAwait *) {1716static IrInstGen *ir_build_suspend_begin_gen(IrAnalyze *ira, IrInst *source_instr) {
1967 return IrInstGenIdAwait;1717 IrInstGenSuspendBegin *inst = ir_build_inst_void<IrInstGenSuspendBegin>(&ira->new_irb,
1718 source_instr->scope, source_instr->source_node);
1719 return &inst->base;
1968}1720}
19691721
1970static constexpr IrInstGenId ir_inst_id(IrInstGenResume *) {1722static IrInstGen *ir_build_save_err_ret_addr_gen(IrAnalyze *ira, IrInst *source_instr) {
1971 return IrInstGenIdResume;1723 IrInstGenSaveErrRetAddr *inst = ir_build_inst_void<IrInstGenSaveErrRetAddr>(&ira->new_irb,
1724 source_instr->scope, source_instr->source_node);
1725 return &inst->base;
1972}1726}
19731727
1974static constexpr IrInstGenId ir_inst_id(IrInstGenSpillBegin *) {1728static IrInstGen *ir_build_truncate_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *dest_type,
1975 return IrInstGenIdSpillBegin;1729 IrInstGen *target)
1976}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 *) {1736 ir_ref_inst_gen(target);
1979 return IrInstGenIdSpillEnd;
1980}
19811737
1982static constexpr IrInstGenId ir_inst_id(IrInstGenVectorExtractElem *) {1738 return &instruction->base;
1983 return IrInstGenIdVectorExtractElem;
1984}1739}
19851740
1986static constexpr IrInstGenId ir_inst_id(IrInstGenAlloca *) {1741static IrInstGen *ir_build_shuffle_vector_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node,
1987 return IrInstGenIdAlloca;1742 ZigType *result_type, IrInstGen *a, IrInstGen *b, IrInstGen *mask)
1988}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 *) {1750 ir_ref_inst_gen(a);
1991 return IrInstGenIdConst;1751 ir_ref_inst_gen(b);
1992}1752 ir_ref_inst_gen(mask);
19931753
1994static constexpr IrInstGenId ir_inst_id(IrInstGenWasmMemorySize *) {1754 return &inst->base;
1995 return IrInstGenIdWasmMemorySize;
1996}1755}
19971756
1998static constexpr IrInstGenId ir_inst_id(IrInstGenWasmMemoryGrow *) {1757static IrInstGen *ir_build_splat_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type,
1999 return IrInstGenIdWasmMemoryGrow;1758 IrInstGen *scalar)
2000}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 *) {1765 ir_ref_inst_gen(scalar);
2003 return IrInstGenIdExtern;
2004}
20051766
2006template<typename T>1767 return &instruction->base;
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;
2015}1768}
20161769
2017template<typename T>1770static IrInstGen *ir_build_bool_not_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value) {
2018static T *ir_create_inst_gen(IrBuilderGen *irb, Scope *scope, AstNode *source_node) {1771 IrInstGenBoolNot *instruction = ir_build_inst_gen<IrInstGenBoolNot>(&ira->new_irb,
2019 T *special_instruction = heap::c_allocator.create<T>();1772 source_instr->scope, source_instr->source_node);
2020 special_instruction->base.id = ir_inst_id(special_instruction);1773 instruction->base.value->type = ira->codegen->builtin_types.entry_bool;
2021 special_instruction->base.base.scope = scope;1774 instruction->value = value;
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}
20281775
2029template<typename T>1776 ir_ref_inst_gen(value);
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}
20391777
2040template<typename T>1778 return &instruction->base;
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;
2045}1779}
20461780
2047template<typename T>1781static IrInstGen *ir_build_memset_gen(IrAnalyze *ira, IrInst *source_instr,
2048static T *ir_build_inst_gen(IrBuilderGen *irb, Scope *scope, AstNode *source_node) {1782 IrInstGen *dest_ptr, IrInstGen *byte, IrInstGen *count)
2049 T *special_instruction = ir_create_inst_gen<T>(irb, scope, source_node);1783{
2050 ir_inst_gen_append(irb->current_basic_block, &special_instruction->base);1784 IrInstGenMemset *instruction = ir_build_inst_void<IrInstGenMemset>(&ira->new_irb,
2051 return special_instruction;1785 source_instr->scope, source_instr->source_node);
2052}1786 instruction->dest_ptr = dest_ptr;
1787 instruction->byte = byte;
1788 instruction->count = count;
20531789
2054template<typename T>1790 ir_ref_inst_gen(dest_ptr);
2055static T *ir_build_inst_noreturn(IrBuilderGen *irb, Scope *scope, AstNode *source_node) {1791 ir_ref_inst_gen(byte);
2056 T *special_instruction = ir_create_inst_noval<T>(irb, scope, source_node);1792 ir_ref_inst_gen(count);
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}
20611793
2062template<typename T>1794 return &instruction->base;
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;
2068}1795}
20691796
2070IrInstGen *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node, ZigFn *fn,1797static IrInstGen *ir_build_memcpy_gen(IrAnalyze *ira, IrInst *source_instr,
2071 ZigType *var_type, const char *name_hint)1798 IrInstGen *dest_ptr, IrInstGen *src_ptr, IrInstGen *count)
2072{1799{
2073 IrInstGenAlloca *alloca_gen = heap::c_allocator.create<IrInstGenAlloca>();1800 IrInstGenMemcpy *instruction = ir_build_inst_void<IrInstGenMemcpy>(&ira->new_irb,
2074 alloca_gen->base.id = IrInstGenIdAlloca;1801 source_instr->scope, source_instr->source_node);
2075 alloca_gen->base.base.source_node = source_node;1802 instruction->dest_ptr = dest_ptr;
2076 alloca_gen->base.base.scope = scope;1803 instruction->src_ptr = src_ptr;
2077 alloca_gen->base.value = g->pass1_arena->create<ZigValue>();1804 instruction->count = count;
2078 alloca_gen->base.value->type = get_pointer_to_type(g, var_type, false);1805
2079 alloca_gen->base.base.ref_count = 1;1806 ir_ref_inst_gen(dest_ptr);
2080 alloca_gen->name_hint = name_hint;1807 ir_ref_inst_gen(src_ptr);
2081 fn->alloca_gen_list.append(alloca_gen);1808 ir_ref_inst_gen(count);
2082 return &alloca_gen->base;1809
1810 return &instruction->base;
2083}1811}
20841812
2085static IrInstGen *ir_build_cast(IrAnalyze *ira, IrInst *source_instr,ZigType *dest_type,1813static IrInstGen *ir_build_slice_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *slice_type,
2086 IrInstGen *value, CastOp cast_op)1814 IrInstGen *ptr, IrInstGen *start, IrInstGen *end, bool safety_check_on, IrInstGen *result_loc,
1815 ZigValue *sentinel)
2087{1816{
2088 IrInstGenCast *inst = ir_build_inst_gen<IrInstGenCast>(&ira->new_irb, source_instr->scope, source_instr->source_node);1817 IrInstGenSlice *instruction = ir_build_inst_gen<IrInstGenSlice>(
2089 inst->base.value->type = dest_type;1818 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
2090 inst->value = value;1819 instruction->base.value->type = slice_type;
2091 inst->cast_op = cast_op;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;
2096}1833}
20971834
2098static IrInstSrc *ir_build_cond_br(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *condition,1835static IrInstGen *ir_build_breakpoint_gen(IrAnalyze *ira, IrInst *source_instr) {
2099 IrBasicBlockSrc *then_block, IrBasicBlockSrc *else_block, IrInstSrc *is_comptime)1836 IrInstGenBreakpoint *instruction = ir_build_inst_void<IrInstGenBreakpoint>(&ira->new_irb,
2100{1837 source_instr->scope, source_instr->source_node);
2101 IrInstSrcCondBr *inst = ir_build_instruction<IrInstSrcCondBr>(irb, scope, source_node);1838 return &instruction->base;
2102 inst->base.is_noreturn = true;1839}
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);
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;
2113 return &inst->base;1844 return &inst->base;
2114}1845}
21151846
2116static IrInstGen *ir_build_cond_br_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *condition,1847static IrInstGen *ir_build_frame_address_gen(IrAnalyze *ira, IrInst *source_instr) {
2117 IrBasicBlockGen *then_block, IrBasicBlockGen *else_block)1848 IrInstGenFrameAddress *inst = ir_build_inst_gen<IrInstGenFrameAddress>(&ira->new_irb, source_instr->scope, source_instr->source_node);
2118{1849 inst->base.value->type = ira->codegen->builtin_types.entry_usize;
2119 IrInstGenCondBr *inst = ir_build_inst_noreturn<IrInstGenCondBr>(&ira->new_irb, source_instr->scope, source_instr->source_node);1850 return &inst->base;
2120 inst->condition = condition;1851}
2121 inst->then_block = then_block;
2122 inst->else_block = else_block;
2123
2124 ir_ref_inst_gen(condition);
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;
2126 return &inst->base;1856 return &inst->base;
2127}1857}
21281858
2129static IrInstSrc *ir_build_return_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *operand) {1859static IrInstGen *ir_build_frame_size_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *fn)
2130 IrInstSrcReturn *inst = ir_build_instruction<IrInstSrcReturn>(irb, scope, source_node);1860{
2131 inst->base.is_noreturn = true;1861 IrInstGenFrameSize *inst = ir_build_inst_gen<IrInstGenFrameSize>(&ira->new_irb, source_instr->scope, source_instr->source_node);
2132 inst->operand = operand;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
2136 return &inst->base;1867 return &inst->base;
2137}1868}
21381869
2139static IrInstGen *ir_build_return_gen(IrAnalyze *ira, IrInst *source_inst, IrInstGen *operand) {1870static IrInstGen *ir_build_overflow_op_gen(IrAnalyze *ira, IrInst *source_instr,
2140 IrInstGenReturn *inst = ir_build_inst_noreturn<IrInstGenReturn>(&ira->new_irb,1871 IrOverflowOp op, IrInstGen *op1, IrInstGen *op2, IrInstGen *result_ptr,
2141 source_inst->scope, source_inst->source_node);1872 ZigType *result_ptr_type)
2142 inst->operand = operand;1873{
21431874 IrInstGenOverflowOp *instruction = ir_build_inst_gen<IrInstGenOverflowOp>(&ira->new_irb,
2144 if (operand != nullptr) ir_ref_inst_gen(operand);1875 source_instr->scope, source_instr->source_node);
21451876 instruction->base.value->type = ira->codegen->builtin_types.entry_bool;
2146 return &inst->base;1877 instruction->op = op;
2147}1878 instruction->op1 = op1;
21481879 instruction->op2 = op2;
2149static IrInstSrc *ir_build_const_void(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) {1880 instruction->result_ptr = result_ptr;
2150 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node);1881 instruction->result_ptr_type = result_ptr_type;
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}
21721882
2173static IrInstSrc *ir_build_const_bigint(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, BigInt *bigint) {1883 ir_ref_inst_gen(op1);
2174 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node);1884 ir_ref_inst_gen(op2);
2175 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();1885 ir_ref_inst_gen(result_ptr);
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}
21811886
2182static IrInstSrc *ir_build_const_bigfloat(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, BigFloat *bigfloat) {1887 return &instruction->base;
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;
2189}1888}
21901889
2191static IrInstSrc *ir_build_const_null(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) {1890static IrInstGen *ir_build_float_op_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand,
2192 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node);1891 BuiltinFnId fn_id, ZigType *operand_type)
2193 ir_instruction_append(irb->current_basic_block, &const_instruction->base);1892{
2194 const_instruction->value = irb->codegen->intern.for_null();1893 IrInstGenFloatOp *instruction = ir_build_inst_gen<IrInstGenFloatOp>(&ira->new_irb,
2195 return &const_instruction->base;1894 source_instr->scope, source_instr->source_node);
2196}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) {1899 ir_ref_inst_gen(operand);
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}
22061900
2207static IrInstSrc *ir_create_const_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,1901 return &instruction->base;
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;
2216}1902}
22171903
2218static IrInstSrc *ir_build_const_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,1904static IrInstGen *ir_build_mul_add_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *op1, IrInstGen *op2,
2219 ZigType *type_entry)1905 IrInstGen *op3, ZigType *expr_type)
2220{1906{
2221 IrInstSrc *instruction = ir_create_const_type(irb, scope, source_node, type_entry);1907 IrInstGenMulAdd *instruction = ir_build_inst_gen<IrInstGenMulAdd>(&ira->new_irb,
2222 ir_instruction_append(irb->current_basic_block, instruction);1908 source_instr->scope, source_instr->source_node);
2223 return instruction;1909 instruction->base.value->type = expr_type;
2224}1910 instruction->op1 = op1;
22251911 instruction->op2 = op2;
2226static IrInstSrc *ir_build_const_import(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigType *import) {1912 instruction->op3 = op3;
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}
22341913
2235static IrInstSrc *ir_build_const_bool(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, bool value) {1914 ir_ref_inst_gen(op1);
2236 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node);1915 ir_ref_inst_gen(op2);
2237 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();1916 ir_ref_inst_gen(op3);
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}
22431917
2244static IrInstSrc *ir_build_const_enum_literal(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *name) {1918 return &instruction->base;
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;
2251}1919}
22521920
2253static IrInstSrc *ir_create_const_str_lit(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *str) {1921static IrInstGen *ir_build_test_err_gen(IrAnalyze *ira, IrInst *source_instruction, IrInstGen *err_union) {
2254 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node);1922 IrInstGenTestErr *instruction = ir_build_inst_gen<IrInstGenTestErr>(
2255 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();1923 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
2256 init_const_str_lit(irb->codegen, const_instruction->value, str);1924 instruction->base.value->type = ira->codegen->builtin_types.entry_bool;
1925 instruction->err_union = err_union;
22571926
2258 return &const_instruction->base;1927 ir_ref_inst_gen(err_union);
2259}
22601928
2261static IrInstSrc *ir_build_const_str_lit(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *str) {1929 return &instruction->base;
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;
2265}1930}
22661931
2267static IrInstSrc *ir_build_bin_op(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrBinOp op_id,1932static IrInstGen *ir_build_unwrap_err_code_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node,
2268 IrInstSrc *op1, IrInstSrc *op2, bool safety_check_on)1933 IrInstGen *err_union_ptr, ZigType *result_type)
2269{1934{
2270 IrInstSrcBinOp *inst = ir_build_instruction<IrInstSrcBinOp>(irb, scope, source_node);1935 IrInstGenUnwrapErrCode *inst = ir_build_inst_gen<IrInstGenUnwrapErrCode>(&ira->new_irb, scope, source_node);
2271 inst->op_id = op_id;1936 inst->base.value->type = result_type;
2272 inst->op1 = op1;1937 inst->err_union_ptr = err_union_ptr;
2273 inst->op2 = op2;
2274 inst->safety_check_on = safety_check_on;
22751938
2276 ir_ref_instruction(op1, irb->current_basic_block);1939 ir_ref_inst_gen(err_union_ptr);
2277 ir_ref_instruction(op2, irb->current_basic_block);
22781940
2279 return &inst->base;1941 return &inst->base;
2280}1942}
22811943
2282static IrInstGen *ir_build_bin_op_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *res_type,1944static IrInstGen *ir_build_unwrap_err_payload_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node,
2283 IrBinOp op_id, IrInstGen *op1, IrInstGen *op2, bool safety_check_on)1945 IrInstGen *value, bool safety_check_on, bool initializing, ZigType *result_type)
2284{1946{
2285 IrInstGenBinOp *inst = ir_build_inst_gen<IrInstGenBinOp>(&ira->new_irb,1947 IrInstGenUnwrapErrPayload *inst = ir_build_inst_gen<IrInstGenUnwrapErrPayload>(&ira->new_irb, scope, source_node);
2286 source_instr->scope, source_instr->source_node);1948 inst->base.value->type = result_type;
2287 inst->base.value->type = res_type;1949 inst->value = value;
2288 inst->op_id = op_id;
2289 inst->op1 = op1;
2290 inst->op2 = op2;
2291 inst->safety_check_on = safety_check_on;1950 inst->safety_check_on = safety_check_on;
1951 inst->initializing = initializing;
22921952
2293 ir_ref_inst_gen(op1);1953 ir_ref_inst_gen(value);
2294 ir_ref_inst_gen(op2);
22951954
2296 return &inst->base;1955 return &inst->base;
2297}1956}
22981957
22991958static IrInstGen *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInst *source_instruction,
2300static IrInstSrc *ir_build_merge_err_sets(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,1959 ZigType *ptr_type, IrInstGen *ptr, bool safety_check_on)
2301 IrInstSrc *op1, IrInstSrc *op2, Buf *type_name)
2302{1960{
2303 IrInstSrcMergeErrSets *inst = ir_build_instruction<IrInstSrcMergeErrSets>(irb, scope, source_node);1961 IrInstGenPtrCast *instruction = ir_build_inst_gen<IrInstGenPtrCast>(
2304 inst->op1 = op1;1962 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
2305 inst->op2 = op2;1963 instruction->base.value->type = ptr_type;
2306 inst->type_name = type_name;1964 instruction->ptr = ptr;
1965 instruction->safety_check_on = safety_check_on;
23071966
2308 ir_ref_instruction(op1, irb->current_basic_block);1967 ir_ref_inst_gen(ptr);
2309 ir_ref_instruction(op2, irb->current_basic_block);
23101968
2311 return &inst->base;1969 return &instruction->base;
2312}1970}
23131971
2314static IrInstSrc *ir_build_var_ptr_x(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigVar *var,1972static IrInstGen *ir_build_bit_cast_gen(IrAnalyze *ira, IrInst *source_instruction,
2315 ScopeFnDef *crossed_fndef_scope)1973 IrInstGen *operand, ZigType *ty)
2316{1974{
2317 IrInstSrcVarPtr *instruction = ir_build_instruction<IrInstSrcVarPtr>(irb, scope, source_node);1975 IrInstGenBitCast *instruction = ir_build_inst_gen<IrInstGenBitCast>(
2318 instruction->var = var;1976 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
2319 instruction->crossed_fndef_scope = crossed_fndef_scope;1977 instruction->base.value->type = ty;
1978 instruction->operand = operand;
23201979
2321 ir_ref_var(var);1980 ir_ref_inst_gen(operand);
23221981
2323 return &instruction->base;1982 return &instruction->base;
2324}1983}
23251984
2326static IrInstSrc *ir_build_var_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigVar *var) {1985static IrInstGen *ir_build_widen_or_shorten(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target,
2327 return ir_build_var_ptr_x(irb, scope, source_node, var, nullptr);1986 ZigType *result_type)
2328}1987{
23291988 IrInstGenWidenOrShorten *inst = ir_build_inst_gen<IrInstGenWidenOrShorten>(&ira->new_irb, scope, source_node);
2330static IrInstGen *ir_build_var_ptr_gen(IrAnalyze *ira, IrInst *source_instr, ZigVar *var) {1989 inst->base.value->type = result_type;
2331 IrInstGenVarPtr *instruction = ir_build_inst_gen<IrInstGenVarPtr>(&ira->new_irb, source_instr->scope, source_instr->source_node);1990 inst->target = target;
2332 instruction->var = var;
23331991
2334 ir_ref_var(var);1992 ir_ref_inst_gen(target);
23351993
2336 return &instruction->base;1994 return &inst->base;
2337}1995}
23381996
2339static IrInstGen *ir_build_return_ptr(IrAnalyze *ira, Scope *scope, AstNode *source_node, ZigType *ty) {1997static IrInstGen *ir_build_int_to_ptr_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node,
2340 IrInstGenReturnPtr *instruction = ir_build_inst_gen<IrInstGenReturnPtr>(&ira->new_irb, scope, source_node);1998 IrInstGen *target, ZigType *ptr_type)
2341 instruction->base.value->type = ty;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
2342 return &instruction->base;2006 return &instruction->base;
2343}2007}
23442008
2345static IrInstSrc *ir_build_elem_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,2009static IrInstGen *ir_build_ptr_to_int_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *target) {
2346 IrInstSrc *array_ptr, IrInstSrc *elem_index, bool safety_check_on, PtrLen ptr_len,2010 IrInstGenPtrToInt *inst = ir_build_inst_gen<IrInstGenPtrToInt>(&ira->new_irb, source_instr->scope, source_instr->source_node);
2347 AstNode *init_array_type_source_node)2011 inst->base.value->type = ira->codegen->builtin_types.entry_usize;
2348{2012 inst->target = target;
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;
23552013
2356 ir_ref_instruction(array_ptr, irb->current_basic_block);2014 ir_ref_inst_gen(target);
2357 ir_ref_instruction(elem_index, irb->current_basic_block);
23582015
2359 return &instruction->base;2016 return &inst->base;
2360}2017}
23612018
2362static IrInstGen *ir_build_elem_ptr_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node,2019static IrInstGen *ir_build_int_to_enum_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node,
2363 IrInstGen *array_ptr, IrInstGen *elem_index, bool safety_check_on, ZigType *return_type)2020 ZigType *dest_type, IrInstGen *target)
2364{2021{
2365 IrInstGenElemPtr *instruction = ir_build_inst_gen<IrInstGenElemPtr>(&ira->new_irb, scope, source_node);2022 IrInstGenIntToEnum *instruction = ir_build_inst_gen<IrInstGenIntToEnum>(&ira->new_irb, scope, source_node);
2366 instruction->base.value->type = return_type;2023 instruction->base.value->type = dest_type;
2367 instruction->array_ptr = array_ptr;2024 instruction->target = target;
2368 instruction->elem_index = elem_index;
2369 instruction->safety_check_on = safety_check_on;
23702025
2371 ir_ref_inst_gen(array_ptr);2026 ir_ref_inst_gen(target);
2372 ir_ref_inst_gen(elem_index);
23732027
2374 return &instruction->base;2028 return &instruction->base;
2375}2029}
23762030
2377static IrInstSrc *ir_build_field_ptr_instruction(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,2031static IrInstGen *ir_build_int_to_err_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target,
2378 IrInstSrc *container_ptr, IrInstSrc *field_name_expr, bool initializing)2032 ZigType *wanted_type)
2379{2033{
2380 IrInstSrcFieldPtr *instruction = ir_build_instruction<IrInstSrcFieldPtr>(irb, scope, source_node);2034 IrInstGenIntToErr *instruction = ir_build_inst_gen<IrInstGenIntToErr>(&ira->new_irb, scope, source_node);
2381 instruction->container_ptr = container_ptr;2035 instruction->base.value->type = wanted_type;
2382 instruction->field_name_buffer = nullptr;2036 instruction->target = target;
2383 instruction->field_name_expr = field_name_expr;
2384 instruction->initializing = initializing;
23852037
2386 ir_ref_instruction(container_ptr, irb->current_basic_block);2038 ir_ref_inst_gen(target);
2387 ir_ref_instruction(field_name_expr, irb->current_basic_block);
23882039
2389 return &instruction->base;2040 return &instruction->base;
2390}2041}
23912042
2392static IrInstSrc *ir_build_field_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,2043static IrInstGen *ir_build_err_to_int_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target,
2393 IrInstSrc *container_ptr, Buf *field_name, bool initializing)2044 ZigType *wanted_type)
2394{2045{
2395 IrInstSrcFieldPtr *instruction = ir_build_instruction<IrInstSrcFieldPtr>(irb, scope, source_node);2046 IrInstGenErrToInt *instruction = ir_build_inst_gen<IrInstGenErrToInt>(&ira->new_irb, scope, source_node);
2396 instruction->container_ptr = container_ptr;2047 instruction->base.value->type = wanted_type;
2397 instruction->field_name_buffer = field_name;2048 instruction->target = target;
2398 instruction->field_name_expr = nullptr;
2399 instruction->initializing = initializing;
24002049
2401 ir_ref_instruction(container_ptr, irb->current_basic_block);2050 ir_ref_inst_gen(target);
24022051
2403 return &instruction->base;2052 return &instruction->base;
2404}2053}
24052054
2406static IrInstSrc *ir_build_has_field(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,2055static IrInstGen *ir_build_panic_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *msg) {
2407 IrInstSrc *container_type, IrInstSrc *field_name)2056 IrInstGenPanic *instruction = ir_build_inst_noreturn<IrInstGenPanic>(&ira->new_irb,
2408{2057 source_instr->scope, source_instr->source_node);
2409 IrInstSrcHasField *instruction = ir_build_instruction<IrInstSrcHasField>(irb, scope, source_node);2058 instruction->msg = msg;
2410 instruction->container_type = container_type;
2411 instruction->field_name = field_name;
24122059
2413 ir_ref_instruction(container_type, irb->current_basic_block);2060 ir_ref_inst_gen(msg);
2414 ir_ref_instruction(field_name, irb->current_basic_block);
24152061
2416 return &instruction->base;2062 return &instruction->base;
2417}2063}
24182064
2419static IrInstGen *ir_build_struct_field_ptr(IrAnalyze *ira, IrInst *source_instr,2065static IrInstGen *ir_build_tag_name_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *target,
2420 IrInstGen *struct_ptr, TypeStructField *field, ZigType *ptr_type)2066 ZigType *result_type)
2421{2067{
2422 IrInstGenStructFieldPtr *inst = ir_build_inst_gen<IrInstGenStructFieldPtr>(&ira->new_irb, source_instr->scope, source_instr->source_node);2068 IrInstGenTagName *instruction = ir_build_inst_gen<IrInstGenTagName>(&ira->new_irb,
2423 inst->base.value->type = ptr_type;2069 source_instr->scope, source_instr->source_node);
2424 inst->struct_ptr = struct_ptr;2070 instruction->base.value->type = result_type;
2425 inst->field = field;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;
2430}2076}
24312077
2432static IrInstGen *ir_build_union_field_ptr(IrAnalyze *ira, IrInst *source_instr,2078static IrInstGen *ir_build_field_parent_ptr_gen(IrAnalyze *ira, IrInst *source_instr,
2433 IrInstGen *union_ptr, TypeUnionField *field, bool safety_check_on, bool initializing, ZigType *ptr_type)2079 IrInstGen *field_ptr, TypeStructField *field, ZigType *result_type)
2434{2080{
2435 IrInstGenUnionFieldPtr *inst = ir_build_inst_gen<IrInstGenUnionFieldPtr>(&ira->new_irb,2081 IrInstGenFieldParentPtr *inst = ir_build_inst_gen<IrInstGenFieldParentPtr>(&ira->new_irb,
2436 source_instr->scope, source_instr->source_node);2082 source_instr->scope, source_instr->source_node);
2437 inst->base.value->type = ptr_type;2083 inst->base.value->type = result_type;
2438 inst->initializing = initializing;2084 inst->field_ptr = field_ptr;
2439 inst->safety_check_on = safety_check_on;
2440 inst->union_ptr = union_ptr;
2441 inst->field = field;2085 inst->field = field;
24422086
2443 ir_ref_inst_gen(union_ptr);2087 ir_ref_inst_gen(field_ptr);
24442088
2445 return &inst->base;2089 return &inst->base;
2446}2090}
24472091
2448static IrInstSrc *ir_build_call_extra(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,2092static IrInstGen *ir_build_align_cast_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target,
2449 IrInstSrc *options, IrInstSrc *fn_ref, IrInstSrc *args, ResultLoc *result_loc)2093 ZigType *result_type)
2450{2094{
2451 IrInstSrcCallExtra *call_instruction = ir_build_instruction<IrInstSrcCallExtra>(irb, scope, source_node);2095 IrInstGenAlignCast *instruction = ir_build_inst_gen<IrInstGenAlignCast>(&ira->new_irb, scope, source_node);
2452 call_instruction->options = options;2096 instruction->base.value->type = result_type;
2453 call_instruction->fn_ref = fn_ref;2097 instruction->target = target;
2454 call_instruction->args = args;
2455 call_instruction->result_loc = result_loc;
24562098
2457 ir_ref_instruction(options, irb->current_basic_block);2099 ir_ref_inst_gen(target);
2458 ir_ref_instruction(fn_ref, irb->current_basic_block);
2459 ir_ref_instruction(args, irb->current_basic_block);
24602100
2461 return &call_instruction->base;2101 return &instruction->base;
2462}2102}
24632103
2464static IrInstSrc *ir_build_async_call_extra(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,2104static IrInstGen *ir_build_error_return_trace_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node,
2465 CallModifier modifier, IrInstSrc *fn_ref, IrInstSrc *ret_ptr, IrInstSrc *new_stack, IrInstSrc *args, ResultLoc *result_loc)2105 IrInstErrorReturnTraceOptional optional, ZigType *result_type)
2466{2106{
2467 IrInstSrcAsyncCallExtra *call_instruction = ir_build_instruction<IrInstSrcAsyncCallExtra>(irb, scope, source_node);2107 IrInstGenErrorReturnTrace *inst = ir_build_inst_gen<IrInstGenErrorReturnTrace>(&ira->new_irb, scope, source_node);
2468 call_instruction->modifier = modifier;2108 inst->base.value->type = result_type;
2469 call_instruction->fn_ref = fn_ref;2109 inst->optional = optional;
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);
24792110
2480 return &call_instruction->base;2111 return &inst->base;
2481}2112}
24822113
2483static IrInstSrc *ir_build_call_args(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,2114static IrInstGen *ir_build_atomic_rmw_gen(IrAnalyze *ira, IrInst *source_instr,
2484 IrInstSrc *options, IrInstSrc *fn_ref, IrInstSrc **args_ptr, size_t args_len,2115 IrInstGen *ptr, IrInstGen *operand, AtomicRmwOp op, AtomicOrder ordering, ZigType *operand_type)
2485 ResultLoc *result_loc)
2486{2116{
2487 IrInstSrcCallArgs *call_instruction = ir_build_instruction<IrInstSrcCallArgs>(irb, scope, source_node);2117 IrInstGenAtomicRmw *instruction = ir_build_inst_gen<IrInstGenAtomicRmw>(&ira->new_irb, source_instr->scope, source_instr->source_node);
2488 call_instruction->options = options;2118 instruction->base.value->type = operand_type;
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);
2770 instruction->ptr = ptr;2119 instruction->ptr = ptr;
2771 instruction->value = value;2120 instruction->op = op;
2121 instruction->operand = operand;
2122 instruction->ordering = ordering;
27722123
2773 ir_ref_inst_gen(ptr);2124 ir_ref_inst_gen(ptr);
2774 ir_ref_inst_gen(value);2125 ir_ref_inst_gen(operand);
27752126
2776 return &instruction->base;2127 return &instruction->base;
2777}2128}
27782129
2779static IrInstGen *ir_build_vector_store_elem(IrAnalyze *ira, IrInst *src_inst,2130static IrInstGen *ir_build_atomic_load_gen(IrAnalyze *ira, IrInst *source_instr,
2780 IrInstGen *vector_ptr, IrInstGen *index, IrInstGen *value)2131 IrInstGen *ptr, AtomicOrder ordering, ZigType *operand_type)
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)
2854{2132{
2855 IrInstGenExtern *instruction = ir_build_inst_gen<IrInstGenExtern>(&ira->new_irb,2133 IrInstGenAtomicLoad *instruction = ir_build_inst_gen<IrInstGenAtomicLoad>(&ira->new_irb,
2856 source_instr->scope, source_instr->source_node);2134 source_instr->scope, source_instr->source_node);
2857 instruction->base.value->type = expr_type;2135 instruction->base.value->type = operand_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;
2880 instruction->ptr = ptr;2136 instruction->ptr = ptr;
2881 instruction->result_loc = result_loc;2137 instruction->ordering = ordering;
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 }
94262138
9427 // next do the non-else non-ranges2139 ir_ref_inst_gen(ptr);
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;
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");2144static IrInstGen *ir_build_atomic_store_gen(IrAnalyze *ira, IrInst *source_instr,
9441 IrInstSrc **items = heap::c_allocator.allocate<IrInstSrc *>(prong_item_count);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) {2153 ir_ref_inst_gen(ptr);
9444 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i);2154 ir_ref_inst_gen(value);
9445 assert(item_node->type != NodeTypeSwitchRange);
94462155
9447 IrInstSrc *item_value = ir_gen_node(irb, item_node, comptime_scope);2156 return &instruction->base;
9448 if (item_value == irb->codegen->invalid_inst_src)2157}
9449 return irb->codegen->invalid_inst_src;
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();2160static IrInstGen *ir_build_vector_to_array(IrAnalyze *ira, IrInst *source_instruction,
9456 this_case->value = item_value;2161 ZigType *result_type, IrInstGen *vector, IrInstGen *result_loc)
9457 this_case->block = prong_block;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;2169 ir_ref_inst_gen(vector);
9460 }2170 ir_ref_inst_gen(result_loc);
94612171
9462 IrBasicBlockSrc *prev_block = irb->current_basic_block;2172 return &instruction->base;
9463 if (peer_parent->peers.length > 0) {2173}
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 }
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,2187 return &instruction->base;
9480 check_ranges.items, check_ranges.length, else_prong, underscore_prong != nullptr);2188}
94812189
9482 IrInstSrc *br_instruction;2190static IrInstGen *ir_build_array_to_vector(IrAnalyze *ira, IrInst *source_instruction,
9483 if (cases.length == 0) {2191 IrInstGen *array, ZigType *result_type)
9484 br_instruction = ir_build_br(irb, scope, node, else_block, is_comptime);2192{
9485 } else {2193 IrInstGenArrayToVector *instruction = ir_build_inst_gen<IrInstGenArrayToVector>(&ira->new_irb,
9486 IrInstSrcSwitchBr *switch_br = ir_build_switch_br_src(irb, scope, node, target_value, else_block,2194 source_instruction->scope, source_instruction->source_node);
9487 cases.length, cases.items, is_comptime, switch_prongs_void);2195 instruction->base.value->type = result_type;
9488 if (switch_else_var != nullptr) {2196 instruction->array = array;
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 }
94992197
9500 if (!else_prong && !underscore_prong) {2198 ir_ref_inst_gen(array);
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 }
95112199
9512 ir_set_cursor_at_end_and_append_block(irb, end_block);2200 return &instruction->base;
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);
9522}2201}
95232202
9524static IrInstSrc *ir_gen_comptime(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval) {2203static IrInstGen *ir_build_assert_zero(IrAnalyze *ira, IrInst *source_instruction,
9525 assert(node->type == NodeTypeCompTime);2204 IrInstGen *target)
95262205{
9527 Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope);2206 IrInstGenAssertZero *instruction = ir_build_inst_gen<IrInstGenAssertZero>(&ira->new_irb,
9528 // purposefully pass null for result_loc and let EndExpr handle it2207 source_instruction->scope, source_instruction->source_node);
9529 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr);2208 instruction->base.value->type = ira->codegen->builtin_types.entry_void;
9530}2209 instruction->target = target;
95312210
9532static IrInstSrc *ir_gen_nosuspend(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval) {2211 ir_ref_inst_gen(target);
9533 assert(node->type == NodeTypeNoSuspend);
95342212
9535 Scope *child_scope = create_nosuspend_scope(irb->codegen, node, parent_scope);2213 return &instruction->base;
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);
9538}2214}
95392215
9540static IrInstSrc *ir_gen_return_from_block(IrBuilderSrc *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) {2216static IrInstGen *ir_build_assert_non_null(IrAnalyze *ira, IrInst *source_instruction,
9541 IrInstSrc *is_comptime;2217 IrInstGen *target)
9542 if (ir_should_inline(irb->exec, break_scope)) {2218{
9543 is_comptime = ir_build_const_bool(irb, break_scope, node, true);2219 IrInstGenAssertNonNull *instruction = ir_build_inst_gen<IrInstGenAssertNonNull>(&ira->new_irb,
9544 } else {2220 source_instruction->scope, source_instruction->source_node);
9545 is_comptime = block_scope->is_comptime;2221 instruction->base.value->type = ira->codegen->builtin_types.entry_void;
9546 }2222 instruction->target = target;
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 }
95602223
9561 IrBasicBlockSrc *dest_block = block_scope->end_block;2224 ir_ref_inst_gen(target);
9562 if (!ir_gen_defers_for_block(irb, break_scope, dest_block->scope, nullptr, nullptr))
9563 return irb->codegen->invalid_inst_src;
95642225
9565 block_scope->incoming_blocks->append(irb->current_basic_block);2226 return &instruction->base;
9566 block_scope->incoming_values->append(result_value);
9567 return ir_build_br(irb, break_scope, node, dest_block, is_comptime);
9568}2227}
95692228
9570static IrInstSrc *ir_gen_break(IrBuilderSrc *irb, Scope *break_scope, AstNode *node) {2229static IrInstGenAlloca *ir_build_alloca_gen(IrAnalyze *ira, IrInst *source_instruction,
9571 assert(node->type == NodeTypeBreak);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:2237 return instruction;
9574 // * function definition scope or global scope => error, break outside loop2238}
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
95782239
9579 Scope *search_scope = break_scope;2240static IrInstGen *ir_build_suspend_finish_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGenSuspendBegin *begin) {
9580 ScopeLoop *loop_scope;2241 IrInstGenSuspendFinish *inst = ir_build_inst_void<IrInstGenSuspendFinish>(&ira->new_irb,
9581 for (;;) {2242 source_instr->scope, source_instr->source_node);
9582 if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) {2243 inst->begin = begin;
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 }
96172244
9618 IrInstSrc *is_comptime;2245 ir_ref_inst_gen(&begin->base);
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 }
96242246
9625 IrInstSrc *result_value;2247 return &inst->base;
9626 if (node->data.break_expr.expr) {2248}
9627 ResultLocPeer *peer_result = create_peer_result(loop_scope->peer_parent);
9628 loop_scope->peer_parent->peers.append(peer_result);
96292249
9630 result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope,2250static IrInstGenAwait *ir_build_await_gen(IrAnalyze *ira, IrInst *source_instruction,
9631 loop_scope->lval, &peer_result->base);2251 IrInstGen *frame, ZigType *result_type, IrInstGen *result_loc, bool is_nosuspend)
9632 if (result_value == irb->codegen->invalid_inst_src)2252{
9633 return irb->codegen->invalid_inst_src;2253 IrInstGenAwait *instruction = ir_build_inst_gen<IrInstGenAwait>(&ira->new_irb,
9634 } else {2254 source_instruction->scope, source_instruction->source_node);
9635 result_value = ir_build_const_void(irb, break_scope, node);2255 instruction->base.value->type = result_type;
9636 }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;2260 ir_ref_inst_gen(frame);
9639 if (!ir_gen_defers_for_block(irb, break_scope, dest_block->scope, nullptr, nullptr))2261 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
9640 return irb->codegen->invalid_inst_src;
96412262
9642 loop_scope->incoming_blocks->append(irb->current_basic_block);2263 return instruction;
9643 loop_scope->incoming_values->append(result_value);
9644 return ir_build_br(irb, break_scope, node, dest_block, is_comptime);
9645}2264}
96462265
9647static IrInstSrc *ir_gen_continue(IrBuilderSrc *irb, Scope *continue_scope, AstNode *node) {2266static IrInstGen *ir_build_resume_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *frame) {
9648 assert(node->type == NodeTypeContinue);2267 IrInstGenResume *instruction = ir_build_inst_void<IrInstGenResume>(&ira->new_irb,
96492268 source_instr->scope, source_instr->source_node);
9650 // Search up the scope. We'll find one of these things first:2269 instruction->frame = frame;
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
96542270
9655 ZigList<ScopeRuntime *> runtime_scopes = {};2271 ir_ref_inst_gen(frame);
96562272
9657 Scope *search_scope = continue_scope;2273 return &instruction->base;
9658 ScopeLoop *loop_scope;2274}
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 }
96862275
9687 IrInstSrc *is_comptime;2276static IrInstGen *ir_build_spill_begin_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand,
9688 if (ir_should_inline(irb->exec, continue_scope)) {2277 SpillId spill_id)
9689 is_comptime = ir_build_const_bool(irb, continue_scope, node, true);2278{
9690 } else {2279 IrInstGenSpillBegin *instruction = ir_build_inst_void<IrInstGenSpillBegin>(&ira->new_irb,
9691 is_comptime = loop_scope->is_comptime;2280 source_instr->scope, source_instr->source_node);
9692 }2281 instruction->operand = operand;
2282 instruction->spill_id = spill_id;
96932283
9694 for (size_t i = 0; i < runtime_scopes.length; i += 1) {2284 ir_ref_inst_gen(operand);
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();
96992285
9700 IrBasicBlockSrc *dest_block = loop_scope->continue_block;2286 return &instruction->base;
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));
9704}2287}
97052288
9706static IrInstSrc *ir_gen_error_type(IrBuilderSrc *irb, Scope *scope, AstNode *node) {2289static IrInstGen *ir_build_spill_end_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGenSpillBegin *begin,
9707 assert(node->type == NodeTypeErrorType);2290 ZigType *result_type)
9708 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_global_error_set);2291{
9709}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) {2299 return &instruction->base;
9712 assert(node->type == NodeTypeDefer);2300}
97132301
9714 ScopeDefer *defer_child_scope = create_defer_scope(irb->codegen, node, parent_scope);2302static IrInstGen *ir_build_vector_extract_elem(IrAnalyze *ira, IrInst *source_instruction,
9715 node->data.defer.child_scope = &defer_child_scope->base;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);2311 ir_ref_inst_gen(vector);
9718 node->data.defer.expr_scope = &defer_expr_scope->base;2312 ir_ref_inst_gen(index);
97192313
9720 return ir_build_const_void(irb, parent_scope, node);2314 return &instruction->base;
9721}2315}
97222316
9723static IrInstSrc *ir_gen_slice(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) {2317static IrInstGen *ir_build_wasm_memory_size_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *index) {
9724 assert(node->type == NodeTypeSliceExpr);2318 IrInstGenWasmMemorySize *instruction = ir_build_inst_gen<IrInstGenWasmMemorySize>(&ira->new_irb,
97252319 source_instr->scope, source_instr->source_node);
9726 AstNodeSliceExpr *slice_expr = &node->data.slice_expr;2320 instruction->base.value->type = ira->codegen->builtin_types.entry_u32;
9727 AstNode *array_node = slice_expr->array_ref_expr;2321 instruction->index = index;
9728 AstNode *start_node = slice_expr->start;
9729 AstNode *end_node = slice_expr->end;
9730 AstNode *sentinel_node = slice_expr->sentinel;
97312322
9732 IrInstSrc *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr, nullptr);2323 ir_ref_inst_gen(index);
9733 if (ptr_value == irb->codegen->invalid_inst_src)
9734 return irb->codegen->invalid_inst_src;
97352324
9736 IrInstSrc *start_value = ir_gen_node(irb, start_node, scope);2325 return &instruction->base;
9737 if (start_value == irb->codegen->invalid_inst_src)2326}
9738 return irb->codegen->invalid_inst_src;
97392327
9740 IrInstSrc *end_value;2328static IrInstGen *ir_build_wasm_memory_grow_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *index, IrInstGen *delta) {
9741 if (end_node) {2329 IrInstGenWasmMemoryGrow *instruction = ir_build_inst_gen<IrInstGenWasmMemoryGrow>(&ira->new_irb,
9742 end_value = ir_gen_node(irb, end_node, scope);2330 source_instr->scope, source_instr->source_node);
9743 if (end_value == irb->codegen->invalid_inst_src)2331 instruction->base.value->type = ira->codegen->builtin_types.entry_i32;
9744 return irb->codegen->invalid_inst_src;2332 instruction->index = index;
9745 } else {2333 instruction->delta = delta;
9746 end_value = nullptr;
9747 }
97482334
9749 IrInstSrc *sentinel_value;2335 ir_ref_inst_gen(index);
9750 if (sentinel_node) {2336 ir_ref_inst_gen(delta);
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 }
97572337
9758 IrInstSrc *slice = ir_build_slice_src(irb, scope, node, ptr_value, start_value, end_value,2338 return &instruction->base;
9759 sentinel_value, true, result_loc);
9760 return ir_lval_wrap(irb, scope, slice, lval, result_loc);
9761}2339}
97622340
9763static IrInstSrc *ir_gen_catch(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval,2341static Error parse_asm_template(IrAnalyze *ira, AstNode *source_node, Buf *asm_template,
9764 ResultLoc *result_loc)2342 ZigList<AsmToken> *tok_list)
9765{2343{
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;2355 AsmToken *cur_tok = nullptr;
9769 AstNode *op2_node = node->data.unwrap_err_expr.op2;2356
9770 AstNode *var_node = node->data.unwrap_err_expr.symbol;2357 enum State state = StateStart;
97712358
9772 if (op2_node->type == NodeTypeUnreachable) {2359 for (size_t i = 0; i < buf_len(asm_template); i += 1) {
9773 if (var_node != nullptr) {2360 uint8_t c = *((uint8_t*)buf_ptr(asm_template) + i);
9774 assert(var_node->type == NodeTypeSymbol);2361 switch (state) {
9775 Buf *var_name = var_node->data.symbol_expr.symbol;2362 case StateStart:
9776 add_node_error(irb->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name)));2363 if (c == '%') {
9777 return irb->codegen->invalid_inst_src;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;
9778 }2417 }
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;
9889 }2418 }
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;2420 switch (state) {
9896 Buf *bare_name = buf_alloc();2421 case StateStart:
9897 Buf *name = get_anon_type_name(irb->codegen, irb->exec, container_string(kind), parent_scope, node, bare_name);2422 break;
98982423 case StatePercent:
9899 ContainerLayout layout = node->data.container_decl.layout;2424 case StateVar:
9900 ZigType *container_type = get_partial_container_type(irb->codegen, parent_scope,2425 add_node_error(ira->codegen, source_node, buf_sprintf("unexpected end of assembly template"));
9901 kind, node, buf_ptr(name), bare_name, layout);2426 return ErrorSemanticAnalyzeFail;
9902 ScopeDecls *child_scope = get_container_scope(container_type);2427 case StateTemplate:
99032428 cur_tok->end = buf_len(asm_template);
9904 for (size_t i = 0; i < node->data.container_decl.decls.length; i += 1) {2429 break;
9905 AstNode *child_node = node->data.container_decl.decls.at(i);
9906 scan_decls(irb->codegen, child_scope, child_node);
9907 }2430 }
99082431 return ErrorNone;
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);
9919}2432}
99202433
9921// errors should be populated with set1's values2434// 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...@@ -10003,498 +2516,7 @@ static ZigType *make_err_set_with_one_item(CodeGen *g, Scope *parent_scope, AstN
10003 return err_set_type;2516 return err_set_type;
10004}2517}
100052518
10006static AstNode *ast_field_to_symbol_node(AstNode *err_set_field_node) {2519static void invalidate_exec_gen(Stage1Air *exec, ErrorMsg *msg) {
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) {
10498 if (exec->first_err_trace_msg != nullptr)2520 if (exec->first_err_trace_msg != nullptr)
10499 return;2521 return;
105002522
...@@ -10509,79 +2531,7 @@ static void invalidate_exec_gen(IrExecutableGen *exec, ErrorMsg *msg) {...@@ -10509,79 +2531,7 @@ static void invalidate_exec_gen(IrExecutableGen *exec, ErrorMsg *msg) {
10509}2531}
105102532
105112533
10512bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutableSrc *ir_executable) {2534static ErrorMsg *exec_add_error_node_gen(CodeGen *codegen, Stage1Air *exec, AstNode *source_node, Buf *msg) {
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) {
10585 ErrorMsg *err_msg = add_node_error(codegen, source_node, msg);2535 ErrorMsg *err_msg = add_node_error(codegen, source_node, msg);
10586 invalidate_exec_gen(exec, err_msg);2536 invalidate_exec_gen(exec, err_msg);
10587 if (exec->parent_exec) {2537 if (exec->parent_exec) {
...@@ -10605,11 +2555,6 @@ static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInst *source_instruction, Buf *m...@@ -10605,11 +2555,6 @@ static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInst *source_instruction, Buf *m
10605 return ir_add_error_node(ira, source_instruction->source_node, msg);2555 return ir_add_error_node(ira, source_instruction->source_node, msg);
10606}2556}
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
10613static void ir_assert_gen_impl(bool ok, IrInstGen *source_instruction, char const *file, unsigned int line) {2558static void ir_assert_gen_impl(bool ok, IrInstGen *source_instruction, char const *file, unsigned int line) {
10614 if (ok) return;2559 if (ok) return;
10615 src_assert_impl(ok, source_instruction->base.source_node, file, line);2560 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...@@ -10660,7 +2605,7 @@ ZigValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ZigValue *const_va
10660 return val;2605 return val;
10661}2606}
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) {
10664 IrBasicBlockGen *bb = exec->basic_block_list.at(0);2609 IrBasicBlockGen *bb = exec->basic_block_list.at(0);
10665 for (size_t i = 0; i < bb->instruction_list.length; i += 1) {2610 for (size_t i = 0; i < bb->instruction_list.length; i += 1) {
10666 IrInstGen *instruction = bb->instruction_list.at(i);2611 IrInstGen *instruction = bb->instruction_list.at(i);
...@@ -10690,7 +2635,7 @@ static Error ir_exec_scan_for_side_effects(CodeGen *codegen, IrExecutableGen *ex...@@ -10690,7 +2635,7 @@ static Error ir_exec_scan_for_side_effects(CodeGen *codegen, IrExecutableGen *ex
10690}2635}
106912636
10692static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInst* source_instruction) {2637static 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)) {
10694 ir_add_error(ira, source_instruction, buf_sprintf("unable to evaluate constant expression"));2639 ir_add_error(ira, source_instruction, buf_sprintf("unable to evaluate constant expression"));
10695 return false;2640 return false;
10696 }2641 }
...@@ -12315,7 +4260,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT...@@ -12315,7 +4260,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
12315 continue;4260 continue;
12316 }4261 }
12317 bool allow_infer = cur_type->data.error_set.infer_fn != nullptr &&4262 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;
12319 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->base.source_node)) {4264 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->base.source_node)) {
12320 return ira->codegen->builtin_types.entry_invalid;4265 return ira->codegen->builtin_types.entry_invalid;
12321 }4266 }
...@@ -12383,7 +4328,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT...@@ -12383,7 +4328,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
12383 }4328 }
12384 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type;4329 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type;
12385 bool allow_infer = cur_err_set_type->data.error_set.infer_fn != nullptr &&4330 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;
12387 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->base.source_node)) {4332 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->base.source_node)) {
12388 return ira->codegen->builtin_types.entry_invalid;4333 return ira->codegen->builtin_types.entry_invalid;
12389 }4334 }
...@@ -12438,7 +4383,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT...@@ -12438,7 +4383,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
124384383
12439 if (cur_type->id == ZigTypeIdErrorSet) {4384 if (cur_type->id == ZigTypeIdErrorSet) {
12440 bool allow_infer = cur_type->data.error_set.infer_fn != nullptr &&4385 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;
12442 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->base.source_node)) {4387 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->base.source_node)) {
12443 return ira->codegen->builtin_types.entry_invalid;4388 return ira->codegen->builtin_types.entry_invalid;
12444 }4389 }
...@@ -12457,7 +4402,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT...@@ -12457,7 +4402,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
12457 if (prev_type->id == ZigTypeIdErrorUnion) {4402 if (prev_type->id == ZigTypeIdErrorUnion) {
12458 err_set_type = prev_type->data.error_union.err_set_type;4403 err_set_type = prev_type->data.error_union.err_set_type;
12459 allow_infer = err_set_type->data.error_set.infer_fn != nullptr &&4404 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;
12461 } else {4406 } else {
12462 err_set_type = cur_type;4407 err_set_type = cur_type;
12463 }4408 }
...@@ -12521,9 +4466,9 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT...@@ -12521,9 +4466,9 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
12521 continue;4466 continue;
125224467
12523 bool allow_infer_prev = prev_err_set_type->data.error_set.infer_fn != nullptr &&4468 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;
12525 bool allow_infer_cur = cur_err_set_type->data.error_set.infer_fn != nullptr &&4470 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
12528 if (!allow_infer_prev && !resolve_inferred_error_set(ira->codegen, prev_err_set_type, cur_inst->base.source_node)) {4473 if (!allow_infer_prev && !resolve_inferred_error_set(ira->codegen, prev_err_set_type, cur_inst->base.source_node)) {
12529 return ira->codegen->builtin_types.entry_invalid;4474 return ira->codegen->builtin_types.entry_invalid;
...@@ -12707,7 +4652,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT...@@ -12707,7 +4652,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
12707 if (err_set_type != nullptr) {4652 if (err_set_type != nullptr) {
12708 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type;4653 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type;
12709 bool allow_infer = cur_err_set_type->data.error_set.infer_fn != nullptr &&4654 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;
12711 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->base.source_node)) {4656 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->base.source_node)) {
12712 return ira->codegen->builtin_types.entry_invalid;4657 return ira->codegen->builtin_types.entry_invalid;
12713 }4658 }
...@@ -13316,7 +5261,7 @@ static IrInstGen *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInst* sourc...@@ -13316,7 +5261,7 @@ static IrInstGen *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInst* sourc
13316 return ir_build_ptr_of_array_to_slice(ira, source_instr, wanted_type, array_ptr, result_loc_inst);5261 return ir_build_ptr_of_array_to_slice(ira, source_instr, wanted_type, array_ptr, result_loc_inst);
13317}5262}
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) {
13320 assert(old_bb);5265 assert(old_bb);
133215266
13322 if (old_bb->child) {5267 if (old_bb->child) {
...@@ -13331,7 +5276,7 @@ static IrBasicBlockGen *ir_get_new_bb(IrAnalyze *ira, IrBasicBlockSrc *old_bb, I...@@ -13331,7 +5276,7 @@ static IrBasicBlockGen *ir_get_new_bb(IrAnalyze *ira, IrBasicBlockSrc *old_bb, I
13331 return new_bb;5276 return new_bb;
13332}5277}
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) {
13335 assert(ref_old_instruction != nullptr);5280 assert(ref_old_instruction != nullptr);
13336 IrBasicBlockGen *new_bb = ir_get_new_bb(ira, old_bb, ref_old_instruction);5281 IrBasicBlockGen *new_bb = ir_get_new_bb(ira, old_bb, ref_old_instruction);
13337 if (new_bb->must_be_comptime_source_instr) {5282 if (new_bb->must_be_comptime_source_instr) {
...@@ -13344,36 +5289,36 @@ static IrBasicBlockGen *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlockSrc *o...@@ -13344,36 +5289,36 @@ static IrBasicBlockGen *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlockSrc *o
13344 return new_bb;5289 return new_bb;
13345}5290}
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) {
13348 ir_assert(!old_bb->suspended, (old_bb->instruction_list.length != 0) ? &old_bb->instruction_list.at(0)->base : nullptr);5293 ir_assert(!old_bb->suspended, (old_bb->instruction_list.length != 0) ? &old_bb->instruction_list.at(0)->base : nullptr);
13349 ira->instruction_index = 0;5294 ira->instruction_index = 0;
13350 ira->old_irb.current_basic_block = old_bb;5295 ira->zir_current_basic_block = old_bb;
13351 ira->const_predecessor_bb = const_predecessor_bb;5296 ira->const_predecessor_bb = const_predecessor_bb;
13352 ira->old_bb_index = old_bb->index;5297 ira->old_bb_index = old_bb->index;
13353}5298}
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,
13356 IrSuspendPosition *suspend_pos)5301 IrSuspendPosition *suspend_pos)
13357{5302{
13358 if (ira->codegen->verbose_ir) {5303 if (ira->codegen->verbose_ir) {
13359 fprintf(stderr, "suspend %s_%" PRIu32 " %s_%" PRIu32 " #%" PRIu32 " (%zu,%zu)\n",5304 fprintf(stderr, "suspend %s_%" PRIu32 " %s_%" PRIu32 " #%" PRIu32 " (%zu,%zu)\n",
13360 ira->old_irb.current_basic_block->name_hint,5305 ira->zir_current_basic_block->name_hint,
13361 ira->old_irb.current_basic_block->debug_id,5306 ira->zir_current_basic_block->debug_id,
13362 ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->name_hint,5307 ira->zir->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,5308 ira->zir->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,5309 ira->zir_current_basic_block->instruction_list.at(ira->instruction_index)->base.debug_id,
13365 ira->old_bb_index, ira->instruction_index);5310 ira->old_bb_index, ira->instruction_index);
13366 }5311 }
13367 suspend_pos->basic_block_index = ira->old_bb_index;5312 suspend_pos->basic_block_index = ira->old_bb_index;
13368 suspend_pos->instruction_index = ira->instruction_index;5313 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
13372 // null next_bb means that the caller plans to call ira_resume before returning5317 // null next_bb means that the caller plans to call ira_resume before returning
13373 if (next_bb != nullptr) {5318 if (next_bb != nullptr) {
13374 ira->old_bb_index = next_bb->index;5319 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);5320 ira->zir_current_basic_block = ira->zir->basic_block_list.at(ira->old_bb_index);
13376 assert(ira->old_irb.current_basic_block == next_bb);5321 assert(ira->zir_current_basic_block == next_bb);
13377 ira->instruction_index = 0;5322 ira->instruction_index = 0;
13378 ira->const_predecessor_bb = nullptr;5323 ira->const_predecessor_bb = nullptr;
13379 next_bb->child = ir_get_new_bb_runtime(ira, next_bb, old_instruction);5324 next_bb->child = ir_get_new_bb_runtime(ira, next_bb, old_instruction);
...@@ -13388,19 +5333,19 @@ static IrInstGen *ira_resume(IrAnalyze *ira) {...@@ -13388,19 +5333,19 @@ static IrInstGen *ira_resume(IrAnalyze *ira) {
13388 fprintf(stderr, "resume (%zu,%zu) ", pos.basic_block_index, pos.instruction_index);5333 fprintf(stderr, "resume (%zu,%zu) ", pos.basic_block_index, pos.instruction_index);
13389 }5334 }
13390 ira->old_bb_index = pos.basic_block_index;5335 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);5336 ira->zir_current_basic_block = ira->zir->basic_block_list.at(ira->old_bb_index);
13392 assert(ira->old_irb.current_basic_block->in_resume_stack);5337 assert(ira->zir_current_basic_block->in_resume_stack);
13393 ira->old_irb.current_basic_block->in_resume_stack = false;5338 ira->zir_current_basic_block->in_resume_stack = false;
13394 ira->old_irb.current_basic_block->suspended = false;5339 ira->zir_current_basic_block->suspended = false;
13395 ira->instruction_index = pos.instruction_index;5340 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);
13397 if (ira->codegen->verbose_ir) {5342 if (ira->codegen->verbose_ir) {
13398 fprintf(stderr, "%s_%" PRIu32 " #%" PRIu32 "\n", ira->old_irb.current_basic_block->name_hint,5343 fprintf(stderr, "%s_%" PRIu32 " #%" PRIu32 "\n", ira->zir_current_basic_block->name_hint,
13399 ira->old_irb.current_basic_block->debug_id,5344 ira->zir_current_basic_block->debug_id,
13400 ira->old_irb.current_basic_block->instruction_list.at(pos.instruction_index)->base.debug_id);5345 ira->zir_current_basic_block->instruction_list.at(pos.instruction_index)->base.debug_id);
13401 }5346 }
13402 ira->const_predecessor_bb = nullptr;5347 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;
13404 assert(ira->new_irb.current_basic_block != nullptr);5349 assert(ira->new_irb.current_basic_block != nullptr);
13405 return ira->codegen->unreach_instruction;5350 return ira->codegen->unreach_instruction;
13406}5351}
...@@ -13410,8 +5355,8 @@ static void ir_start_next_bb(IrAnalyze *ira) {...@@ -13410,8 +5355,8 @@ static void ir_start_next_bb(IrAnalyze *ira) {
134105355
13411 bool need_repeat = true;5356 bool need_repeat = true;
13412 for (;;) {5357 for (;;) {
13413 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) {5358 while (ira->old_bb_index < ira->zir->basic_block_list.length) {
13414 IrBasicBlockSrc *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index);5359 Stage1ZirBasicBlock *old_bb = ira->zir->basic_block_list.at(ira->old_bb_index);
13415 if (old_bb->child == nullptr && old_bb->suspend_instruction_ref == nullptr) {5360 if (old_bb->child == nullptr && old_bb->suspend_instruction_ref == nullptr) {
13416 ira->old_bb_index += 1;5361 ira->old_bb_index += 1;
13417 continue;5362 continue;
...@@ -13463,8 +5408,8 @@ static void ir_finish_bb(IrAnalyze *ira) {...@@ -13463,8 +5408,8 @@ static void ir_finish_bb(IrAnalyze *ira) {
13463 }5408 }
13464 }5409 }
13465 ira->instruction_index += 1;5410 ira->instruction_index += 1;
13466 while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) {5411 while (ira->instruction_index < ira->zir_current_basic_block->instruction_list.length) {
13467 IrInstSrc *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index);5412 IrInstSrc *next_instruction = ira->zir_current_basic_block->instruction_list.at(ira->instruction_index);
13468 if (!next_instruction->is_gen) {5413 if (!next_instruction->is_gen) {
13469 ir_add_error(ira, &next_instruction->base, buf_sprintf("unreachable code"));5414 ir_add_error(ira, &next_instruction->base, buf_sprintf("unreachable code"));
13470 break;5415 break;
...@@ -13484,8 +5429,8 @@ static IrInstGen *ir_unreach_error(IrAnalyze *ira) {...@@ -13484,8 +5429,8 @@ static IrInstGen *ir_unreach_error(IrAnalyze *ira) {
13484}5429}
134855430
13486static bool ir_emit_backward_branch(IrAnalyze *ira, IrInst* source_instruction) {5431static bool ir_emit_backward_branch(IrAnalyze *ira, IrInst* source_instruction) {
13487 size_t *bbc = ira->new_irb.exec->backward_branch_count;5432 size_t *bbc = ira->backward_branch_count;
13488 size_t *quota = ira->new_irb.exec->backward_branch_quota;5433 size_t *quota = ira->backward_branch_quota;
134895434
13490 // If we're already over quota, we've already given an error message for this.5435 // If we're already over quota, we've already given an error message for this.
13491 if (*bbc > *quota) {5436 if (*bbc > *quota) {
...@@ -13502,14 +5447,14 @@ static bool ir_emit_backward_branch(IrAnalyze *ira, IrInst* source_instruction)...@@ -13502,14 +5447,14 @@ static bool ir_emit_backward_branch(IrAnalyze *ira, IrInst* source_instruction)
13502 return true;5447 return true;
13503}5448}
135045449
13505static IrInstGen *ir_inline_bb(IrAnalyze *ira, IrInst* source_instruction, IrBasicBlockSrc *old_bb) {5450static IrInstGen *ir_inline_bb(IrAnalyze *ira, IrInst* source_instruction, Stage1ZirBasicBlock *old_bb) {
13506 if (old_bb->debug_id <= ira->old_irb.current_basic_block->debug_id) {5451 if (old_bb->debug_id <= ira->zir_current_basic_block->debug_id) {
13507 if (!ir_emit_backward_branch(ira, source_instruction))5452 if (!ir_emit_backward_branch(ira, source_instruction))
13508 return ir_unreach_error(ira);5453 return ir_unreach_error(ira);
13509 }5454 }
135105455
13511 old_bb->child = ira->old_irb.current_basic_block->child;5456 old_bb->child = ira->zir_current_basic_block->child;
13512 ir_start_bb(ira, old_bb, ira->old_irb.current_basic_block);5457 ir_start_bb(ira, old_bb, ira->zir_current_basic_block);
13513 return ira->codegen->unreach_instruction;5458 return ira->codegen->unreach_instruction;
13514}5459}
135155460
...@@ -13591,7 +5536,7 @@ static IrInstGen *ir_get_const_ptr(IrAnalyze *ira, IrInst *instruction,...@@ -13591,7 +5536,7 @@ static IrInstGen *ir_get_const_ptr(IrAnalyze *ira, IrInst *instruction,
13591 return const_instr;5536 return const_instr;
13592}5537}
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,
13595 ZigValue *val, UndefAllowed undef_allowed)5540 ZigValue *val, UndefAllowed undef_allowed)
13596{5541{
13597 Error err;5542 Error err;
...@@ -13638,7 +5583,7 @@ static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstGen *value, UndefAllowed...@@ -13638,7 +5583,7 @@ static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstGen *value, UndefAllowed
13638Error ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,5583Error ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
13639 ZigValue *return_ptr, size_t *backward_branch_count, size_t *backward_branch_quota,5584 ZigValue *return_ptr, size_t *backward_branch_count, size_t *backward_branch_quota,
13640 ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name,5585 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)
13642{5587{
13643 Error err;5588 Error err;
136445589
...@@ -13647,43 +5592,38 @@ Error ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,...@@ -13647,43 +5592,38 @@ Error ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
13647 if (type_is_invalid(return_ptr->type))5592 if (type_is_invalid(return_ptr->type))
13648 return ErrorSemanticAnalyzeFail;5593 return ErrorSemanticAnalyzeFail;
136495594
13650 IrExecutableSrc *ir_executable = heap::c_allocator.create<IrExecutableSrc>();5595 Stage1Zir *stage1_zir = heap::c_allocator.create<Stage1Zir>();
13651 ir_executable->source_node = source_node;5596 stage1_zir->name = exec_name;
13652 ir_executable->parent_exec = parent_exec;5597 stage1_zir->is_inline = true;
13653 ir_executable->name = exec_name;5598 stage1_zir->begin_scope = scope;
13654 ir_executable->is_inline = true;5599
13655 ir_executable->fn_entry = fn_entry;5600 bool in_c_import_scope = c_import_buf != nullptr;
13656 ir_executable->c_import_buf = c_import_buf;
13657 ir_executable->begin_scope = scope;
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))
13660 return ErrorSemanticAnalyzeFail;5603 return ErrorSemanticAnalyzeFail;
136615604
13662 if (ir_executable->first_err_trace_msg != nullptr) {5605 if (stage1_zir->first_err_trace_msg != nullptr) {
13663 codegen->trace_err = ir_executable->first_err_trace_msg;5606 codegen->trace_err = stage1_zir->first_err_trace_msg;
13664 return ErrorSemanticAnalyzeFail;5607 return ErrorSemanticAnalyzeFail;
13665 }5608 }
136665609
13667 if (codegen->verbose_ir) {5610 if (codegen->verbose_ir) {
13668 fprintf(stderr, "\nSource: ");
13669 ast_render(stderr, node, 4);
13670 fprintf(stderr, "\n{ // (IR)\n");5611 fprintf(stderr, "\n{ // (IR)\n");
13671 ir_print_src(codegen, stderr, ir_executable, 2);5612 ir_print_src(codegen, stderr, stage1_zir, 2);
13672 fprintf(stderr, "}\n");5613 fprintf(stderr, "}\n");
13673 }5614 }
13674 IrExecutableGen *analyzed_executable = heap::c_allocator.create<IrExecutableGen>();5615 Stage1Air *analyzed_executable = heap::c_allocator.create<Stage1Air>();
13675 analyzed_executable->source_node = source_node;5616 analyzed_executable->source_node = source_node;
13676 analyzed_executable->parent_exec = parent_exec;5617 analyzed_executable->parent_exec = parent_exec;
13677 analyzed_executable->source_exec = ir_executable;5618 analyzed_executable->source_exec = stage1_zir;
13678 analyzed_executable->name = exec_name;5619 analyzed_executable->name = exec_name;
13679 analyzed_executable->is_inline = true;5620 analyzed_executable->is_inline = true;
13680 analyzed_executable->fn_entry = fn_entry;
13681 analyzed_executable->c_import_buf = c_import_buf;5621 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;
13684 analyzed_executable->begin_scope = scope;5622 analyzed_executable->begin_scope = scope;
13685 ZigType *result_type = ir_analyze(codegen, ir_executable, analyzed_executable,5623 ZigType *result_type = ir_analyze(codegen, stage1_zir, analyzed_executable,
13686 return_ptr->type->data.pointer.child_type, expected_type_source_node, return_ptr);5624 backward_branch_count, backward_branch_quota,
5625 return_ptr->type->data.pointer.child_type, expected_type_source_node, return_ptr,
5626 fn_entry);
13687 if (type_is_invalid(result_type)) {5627 if (type_is_invalid(result_type)) {
13688 return ErrorSemanticAnalyzeFail;5628 return ErrorSemanticAnalyzeFail;
13689 }5629 }
...@@ -13724,7 +5664,7 @@ static ErrorTableEntry *ir_resolve_error(IrAnalyze *ira, IrInstGen *err_value) {...@@ -13724,7 +5664,7 @@ static ErrorTableEntry *ir_resolve_error(IrAnalyze *ira, IrInstGen *err_value) {
13724 return const_val->data.x_err_set;5664 return const_val->data.x_err_set;
13725}5665}
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,
13728 ZigValue *val)5668 ZigValue *val)
13729{5669{
13730 Error err;5670 Error err;
...@@ -14976,7 +6916,7 @@ static IrInstGen *ir_analyze_struct_literal_to_array(IrAnalyze *ira, IrInst* sou...@@ -14976,7 +6916,7 @@ static IrInstGen *ir_analyze_struct_literal_to_array(IrAnalyze *ira, IrInst* sou
14976 size_t instr_field_count = actual_type->data.structure.src_field_count;6916 size_t instr_field_count = actual_type->data.structure.src_field_count;
14977 assert(array_len == instr_field_count);6917 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)
14980 || type_requires_comptime(ira->codegen, wanted_type) == ReqCompTimeYes;6920 || type_requires_comptime(ira->codegen, wanted_type) == ReqCompTimeYes;
14981 bool is_comptime = true;6921 bool is_comptime = true;
149826922
...@@ -15066,7 +7006,7 @@ static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInst* so...@@ -15066,7 +7006,7 @@ static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInst* so
15066 size_t actual_field_count = wanted_type->data.structure.src_field_count;7006 size_t actual_field_count = wanted_type->data.structure.src_field_count;
15067 size_t instr_field_count = actual_type->data.structure.src_field_count;7007 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)
15070 || type_requires_comptime(ira->codegen, wanted_type) == ReqCompTimeYes;7010 || type_requires_comptime(ira->codegen, wanted_type) == ReqCompTimeYes;
15071 bool is_comptime = true;7011 bool is_comptime = true;
150727012
...@@ -16132,7 +8072,7 @@ static IrInstGen *ir_get_deref(IrAnalyze *ira, IrInst* source_instruction, IrIns...@@ -16132,7 +8072,7 @@ static IrInstGen *ir_get_deref(IrAnalyze *ira, IrInst* source_instruction, IrIns
16132 return ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type, result_loc_inst);8072 return ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type, result_loc_inst);
16133}8073}
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,
16136 ZigValue *const_val, uint32_t *out)8076 ZigValue *const_val, uint32_t *out)
16137{8077{
16138 Error err;8078 Error err;
...@@ -19085,7 +11025,7 @@ static IrInstGen *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstSrcDeclV...@@ -19085,7 +11025,7 @@ static IrInstGen *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstSrcDeclV
19085 return ira->codegen->invalid_inst_gen;11025 return ira->codegen->invalid_inst_gen;
19086 }11026 }
1908711027
19088 ZigFn *fn_entry = ira->new_irb.exec->fn_entry;11028 ZigFn *fn_entry = ira->fn;
19089 if (fn_entry)11029 if (fn_entry)
19090 fn_entry->variable_list.append(var);11030 fn_entry->variable_list.append(var);
1909111031
...@@ -19481,9 +11421,9 @@ static IrInstGen *ir_analyze_instruction_extern(IrAnalyze *ira, IrInstSrcExtern...@@ -19481,9 +11421,9 @@ static IrInstGen *ir_analyze_instruction_extern(IrAnalyze *ira, IrInstSrcExtern
19481 is_thread_local, expr_type);11421 is_thread_local, expr_type);
19482}11422}
1948311423
19484static bool exec_has_err_ret_trace(CodeGen *g, IrExecutableSrc *exec) {11424static bool ira_has_err_ret_trace(IrAnalyze *ira) {
19485 ZigFn *fn_entry = exec_fn_entry(exec);11425 ZigFn *fn = ira->fn;
19486 return fn_entry != nullptr && fn_entry->calls_or_awaits_errorable_fn && g->have_err_ret_tracing;11426 return fn != nullptr && fn->calls_or_awaits_errorable_fn && ira->codegen->have_err_ret_tracing;
19487}11427}
1948811428
19489static IrInstGen *ir_analyze_instruction_error_return_trace(IrAnalyze *ira,11429static IrInstGen *ir_analyze_instruction_error_return_trace(IrAnalyze *ira,
...@@ -19492,7 +11432,7 @@ static IrInstGen *ir_analyze_instruction_error_return_trace(IrAnalyze *ira,...@@ -19492,7 +11432,7 @@ static IrInstGen *ir_analyze_instruction_error_return_trace(IrAnalyze *ira,
19492 ZigType *ptr_to_stack_trace_type = get_pointer_to_type(ira->codegen, get_stack_trace_type(ira->codegen), false);11432 ZigType *ptr_to_stack_trace_type = get_pointer_to_type(ira->codegen, get_stack_trace_type(ira->codegen), false);
19493 if (instruction->optional == IrInstErrorReturnTraceNull) {11433 if (instruction->optional == IrInstErrorReturnTraceNull) {
19494 ZigType *optional_type = get_optional_type(ira->codegen, ptr_to_stack_trace_type);11434 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)) {
19496 IrInstGen *result = ir_const(ira, &instruction->base.base, optional_type);11436 IrInstGen *result = ir_const(ira, &instruction->base.base, optional_type);
19497 ZigValue *out_val = result->value;11437 ZigValue *out_val = result->value;
19498 assert(get_src_ptr_type(optional_type) != nullptr);11438 assert(get_src_ptr_type(optional_type) != nullptr);
...@@ -19564,7 +11504,7 @@ static IrInstGen *ir_analyze_alloca(IrAnalyze *ira, IrInst *source_inst, ZigType...@@ -19564,7 +11504,7 @@ static IrInstGen *ir_analyze_alloca(IrAnalyze *ira, IrInst *source_inst, ZigType
19564 PtrLenSingle, align, 0, 0, false);11504 PtrLenSingle, align, 0, 0, false);
1956511505
19566 if (!force_comptime) {11506 if (!force_comptime) {
19567 ZigFn *fn_entry = ira->new_irb.exec->fn_entry;11507 ZigFn *fn_entry = ira->fn;
19568 if (fn_entry != nullptr) {11508 if (fn_entry != nullptr) {
19569 fn_entry->alloca_gen_list.append(result);11509 fn_entry->alloca_gen_list.append(result);
19570 }11510 }
...@@ -19663,7 +11603,7 @@ static IrInstGen *ir_resolve_no_result_loc(IrAnalyze *ira, IrInst *suspend_sourc...@@ -19663,7 +11603,7 @@ static IrInstGen *ir_resolve_no_result_loc(IrAnalyze *ira, IrInst *suspend_sourc
19663 alloca_gen->base.value->type = get_pointer_to_type_extra(ira->codegen, value_type, false, false,11603 alloca_gen->base.value->type = get_pointer_to_type_extra(ira->codegen, value_type, false, false,
19664 PtrLenSingle, 0, 0, 0, false);11604 PtrLenSingle, 0, 0, 0, false);
19665 set_up_result_loc_for_inferred_comptime(ira, &alloca_gen->base);11605 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;
19667 if (fn_entry != nullptr && get_scope_typeof(suspend_source_instr->scope) == nullptr) {11607 if (fn_entry != nullptr && get_scope_typeof(suspend_source_instr->scope) == nullptr) {
19668 fn_entry->alloca_gen_list.append(alloca_gen);11608 fn_entry->alloca_gen_list.append(alloca_gen);
19669 }11609 }
...@@ -20191,7 +12131,7 @@ static IrInstGen *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstSr...@@ -20191,7 +12131,7 @@ static IrInstGen *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstSr
20191 if (result_loc != nullptr)12131 if (result_loc != nullptr)
20192 return result_loc;12132 return result_loc;
2019312133
20194 ZigFn *fn = ira->new_irb.exec->fn_entry;12134 ZigFn *fn = ira->fn;
20195 if (fn != nullptr && fn->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync &&12135 if (fn != nullptr && fn->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync &&
20196 instruction->result_loc->id == ResultLocIdReturn)12136 instruction->result_loc->id == ResultLocIdReturn)
20197 {12137 {
...@@ -20319,7 +12259,7 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node...@@ -20319,7 +12259,7 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node
20319 assert(param_decl_node->type == NodeTypeParamDecl);12259 assert(param_decl_node->type == NodeTypeParamDecl);
2032012260
20321 IrInstGen *casted_arg;12261 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) {
20323 AstNode *param_type_node = param_decl_node->data.param_decl.type;12263 AstNode *param_type_node = param_decl_node->data.param_decl.type;
20324 ZigType *param_type = ir_analyze_type_expr(ira, *exec_scope, param_type_node);12264 ZigType *param_type = ir_analyze_type_expr(ira, *exec_scope, param_type_node);
20325 if (type_is_invalid(param_type))12265 if (type_is_invalid(param_type))
...@@ -20362,7 +12302,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod...@@ -20362,7 +12302,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
20362 casted_arg = arg;12302 casted_arg = arg;
20363 param_info_type = arg->value->type;12303 param_info_type = arg->value->type;
20364 } else {12304 } else {
20365 if (param_decl_node->data.param_decl.anytype_token == nullptr) {12305 if (param_decl_node->data.param_decl.anytype_token == 0) {
20366 AstNode *param_type_node = param_decl_node->data.param_decl.type;12306 AstNode *param_type_node = param_decl_node->data.param_decl.type;
20367 ZigType *param_type = ir_analyze_type_expr(ira, *child_scope, param_type_node);12307 ZigType *param_type = ir_analyze_type_expr(ira, *child_scope, param_type_node);
20368 if (type_is_invalid(param_type))12308 if (type_is_invalid(param_type))
...@@ -20813,7 +12753,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,...@@ -20813,7 +12753,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
20813 create_result_ptr(ira->codegen, return_type, &result, &result_ptr);12753 create_result_ptr(ira->codegen, return_type, &result, &result_ptr);
2081412754
20815 if ((err = ir_eval_const_value(ira->codegen, exec_scope, body_node, result_ptr,12755 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,
20817 fn_entry, nullptr, source_instr->source_node, nullptr, ira->new_irb.exec, return_type_node,12757 fn_entry, nullptr, source_instr->source_node, nullptr, ira->new_irb.exec, return_type_node,
20818 UndefOk)))12758 UndefOk)))
20819 {12759 {
...@@ -20909,7 +12849,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,...@@ -20909,7 +12849,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
20909 }12849 }
20910 }12850 }
2091112851
20912 ZigFn *parent_fn_entry = ira->new_irb.exec->fn_entry;12852 ZigFn *parent_fn_entry = ira->fn;
20913 assert(parent_fn_entry);12853 assert(parent_fn_entry);
20914 for (size_t call_i = 0; call_i < args_len; call_i += 1) {12854 for (size_t call_i = 0; call_i < args_len; call_i += 1) {
20915 IrInstGen *arg = args_ptr[call_i];12855 IrInstGen *arg = args_ptr[call_i];
...@@ -20930,7 +12870,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,...@@ -20930,7 +12870,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
20930 create_result_ptr(ira->codegen, get_align_amt_type(ira->codegen), &align_result, &result_ptr);12870 create_result_ptr(ira->codegen, get_align_amt_type(ira->codegen), &align_result, &result_ptr);
20931 if ((err = ir_eval_const_value(ira->codegen, impl_fn->child_scope,12871 if ((err = ir_eval_const_value(ira->codegen, impl_fn->child_scope,
20932 fn_proto_node->data.fn_proto.align_expr, result_ptr,12872 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,
20934 nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec,12874 nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec,
20935 nullptr, UndefBad)))12875 nullptr, UndefBad)))
20936 {12876 {
...@@ -20994,12 +12934,9 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,...@@ -20994,12 +12934,9 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
20994 if (type_is_invalid(impl_fn->type_entry))12934 if (type_is_invalid(impl_fn->type_entry))
20995 return ira->codegen->invalid_inst_gen;12935 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;
20999 impl_fn->analyzed_executable.source_node = source_instr->source_node;12937 impl_fn->analyzed_executable.source_node = source_instr->source_node;
21000 impl_fn->analyzed_executable.parent_exec = ira->new_irb.exec;12938 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;12939 impl_fn->branch_quota = *ira->backward_branch_quota;
21002 impl_fn->analyzed_executable.is_generic_instantiation = true;
2100312940
21004 ira->codegen->fn_defs.append(impl_fn);12941 ira->codegen->fn_defs.append(impl_fn);
21005 }12942 }
...@@ -21079,7 +13016,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,...@@ -21079,7 +13016,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
21079 return ir_finish_anal(ira, &new_call_instruction->base);13016 return ir_finish_anal(ira, &new_call_instruction->base);
21080 }13017 }
2108113018
21082 ZigFn *parent_fn_entry = ira->new_irb.exec->fn_entry;13019 ZigFn *parent_fn_entry = ira->fn;
21083 assert(fn_type_id->return_type != nullptr);13020 assert(fn_type_id->return_type != nullptr);
21084 assert(parent_fn_entry != nullptr);13021 assert(parent_fn_entry != nullptr);
21085 if (fn_type_can_fail(fn_type_id)) {13022 if (fn_type_can_fail(fn_type_id)) {
...@@ -21275,7 +13212,7 @@ static IrInstGen *ir_analyze_call_extra(IrAnalyze *ira, IrInst* source_instr,...@@ -21275,7 +13212,7 @@ static IrInstGen *ir_analyze_call_extra(IrAnalyze *ira, IrInst* source_instr,
21275 return ira->codegen->invalid_inst_gen;13212 return ira->codegen->invalid_inst_gen;
21276 CallModifier modifier = (CallModifier)bigint_as_u32(&modifier_val->data.x_enum_tag);13213 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)) {
21279 switch (modifier) {13216 switch (modifier) {
21280 case CallModifierBuiltin:13217 case CallModifierBuiltin:
21281 zig_unreachable();13218 zig_unreachable();
...@@ -21364,7 +13301,7 @@ static IrInstGen *ir_analyze_async_call_extra(IrAnalyze *ira, IrInst* source_ins...@@ -21364,7 +13301,7 @@ static IrInstGen *ir_analyze_async_call_extra(IrAnalyze *ira, IrInst* source_ins
21364 if (type_is_invalid(fn_ref->value->type))13301 if (type_is_invalid(fn_ref->value->type))
21365 return ira->codegen->invalid_inst_gen;13302 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)) {
21368 ir_add_error(ira, source_instr, buf_sprintf("TODO: comptime @asyncCall"));13305 ir_add_error(ira, source_instr, buf_sprintf("TODO: comptime @asyncCall"));
21369 return ira->codegen->invalid_inst_gen;13306 return ira->codegen->invalid_inst_gen;
21370 }13307 }
...@@ -21477,7 +13414,7 @@ static IrInstGen *ir_analyze_instruction_call(IrAnalyze *ira, IrInstSrcCall *cal...@@ -21477,7 +13414,7 @@ static IrInstGen *ir_analyze_instruction_call(IrAnalyze *ira, IrInstSrcCall *cal
21477 return ira->codegen->invalid_inst_gen;13414 return ira->codegen->invalid_inst_gen;
2147813415
21479 bool is_comptime = (call_instruction->modifier == CallModifierCompileTime) ||13416 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);
21481 CallModifier modifier = is_comptime ? CallModifierCompileTime : call_instruction->modifier;13418 CallModifier modifier = is_comptime ? CallModifierCompileTime : call_instruction->modifier;
2148213419
21483 if (is_comptime || instr_is_comptime(fn_ref)) {13420 if (is_comptime || instr_is_comptime(fn_ref)) {
...@@ -21839,20 +13776,20 @@ static IrInstGen *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstSrcUnOp *in...@@ -21839,20 +13776,20 @@ static IrInstGen *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstSrcUnOp *in
21839}13776}
2184013777
21841static void ir_push_resume(IrAnalyze *ira, IrSuspendPosition pos) {13778static 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);
21843 if (old_bb->in_resume_stack) return;13780 if (old_bb->in_resume_stack) return;
21844 ira->resume_stack.append(pos);13781 ira->resume_stack.append(pos);
21845 old_bb->in_resume_stack = true;13782 old_bb->in_resume_stack = true;
21846}13783}
2184713784
21848static void ir_push_resume_block(IrAnalyze *ira, IrBasicBlockSrc *old_bb) {13785static void ir_push_resume_block(IrAnalyze *ira, Stage1ZirBasicBlock *old_bb) {
21849 if (ira->resume_stack.length != 0) {13786 if (ira->resume_stack.length != 0) {
21850 ir_push_resume(ira, {old_bb->index, 0});13787 ir_push_resume(ira, {old_bb->index, 0});
21851 }13788 }
21852}13789}
2185313790
21854static IrInstGen *ir_analyze_instruction_br(IrAnalyze *ira, IrInstSrcBr *br_instruction) {13791static 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
21857 bool is_comptime;13794 bool is_comptime;
21858 if (!ir_resolve_comptime(ira, br_instruction->is_comptime->child, &is_comptime))13795 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...@@ -21890,7 +13827,7 @@ static IrInstGen *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstSrcCondBr
21890 if (!ir_resolve_bool(ira, casted_condition, &cond_is_true))13827 if (!ir_resolve_bool(ira, casted_condition, &cond_is_true))
21891 return ir_unreach_error(ira);13828 return ir_unreach_error(ira);
2189213829
21893 IrBasicBlockSrc *old_dest_block = cond_is_true ?13830 Stage1ZirBasicBlock *old_dest_block = cond_is_true ?
21894 cond_br_instruction->then_block : cond_br_instruction->else_block;13831 cond_br_instruction->then_block : cond_br_instruction->else_block;
2189513832
21896 if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr))13833 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...@@ -21926,7 +13863,7 @@ static IrInstGen *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstSrcCondBr
21926static IrInstGen *ir_analyze_instruction_unreachable(IrAnalyze *ira,13863static IrInstGen *ir_analyze_instruction_unreachable(IrAnalyze *ira,
21927 IrInstSrcUnreachable *unreachable_instruction)13864 IrInstSrcUnreachable *unreachable_instruction)
21928{13865{
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)) {
21930 ir_add_error(ira, &unreachable_instruction->base.base, buf_sprintf("reached unreachable code"));13867 ir_add_error(ira, &unreachable_instruction->base.base, buf_sprintf("reached unreachable code"));
21931 return ir_unreach_error(ira);13868 return ir_unreach_error(ira);
21932 }13869 }
...@@ -21940,7 +13877,7 @@ static IrInstGen *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstSrcPhi *phi_i...@@ -21940,7 +13877,7 @@ static IrInstGen *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstSrcPhi *phi_i
2194013877
21941 if (ira->const_predecessor_bb) {13878 if (ira->const_predecessor_bb) {
21942 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) {13879 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];
21944 if (predecessor != ira->const_predecessor_bb)13881 if (predecessor != ira->const_predecessor_bb)
21945 continue;13882 continue;
21946 IrInstGen *value = phi_instruction->incoming_values[i]->child;13883 IrInstGen *value = phi_instruction->incoming_values[i]->child;
...@@ -22040,7 +13977,7 @@ static IrInstGen *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstSrcPhi *phi_i...@@ -22040,7 +13977,7 @@ static IrInstGen *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstSrcPhi *phi_i
22040 ZigList<IrInstGen*> new_incoming_values = {0};13977 ZigList<IrInstGen*> new_incoming_values = {0};
2204113978
22042 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) {13979 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];
22044 if (predecessor->ref_count == 0)13981 if (predecessor->ref_count == 0)
22045 continue;13982 continue;
2204613983
...@@ -23593,6 +15530,25 @@ static IrInstGen *ir_analyze_instruction_slice_type(IrAnalyze *ira, IrInstSrcSli...@@ -23593,6 +15530,25 @@ static IrInstGen *ir_analyze_instruction_slice_type(IrAnalyze *ira, IrInstSrcSli
23593 return result;15530 return result;
23594}15531}
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
23596static IrInstGen *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstSrcAsm *asm_instruction) {15552static IrInstGen *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstSrcAsm *asm_instruction) {
23597 Error err;15553 Error err;
2359815554
...@@ -24040,7 +15996,7 @@ static IrInstGen *ir_analyze_instruction_switch_br(IrAnalyze *ira,...@@ -24040,7 +15996,7 @@ static IrInstGen *ir_analyze_instruction_switch_br(IrAnalyze *ira,
24040 if (!target_val)15996 if (!target_val)
24041 return ir_unreach_error(ira);15997 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;
24044 for (size_t i = 0; i < case_count; i += 1) {16000 for (size_t i = 0; i < case_count; i += 1) {
24045 IrInstSrcSwitchBrCase *old_case = &switch_br_instruction->cases[i];16001 IrInstSrcSwitchBrCase *old_case = &switch_br_instruction->cases[i];
24046 IrInstGen *case_value = old_case->value->child;16002 IrInstGen *case_value = old_case->value->child;
...@@ -24522,7 +16478,7 @@ static IrInstGen *ir_analyze_union_init(IrAnalyze *ira, IrInst* source_instructi...@@ -24522,7 +16478,7 @@ static IrInstGen *ir_analyze_union_init(IrAnalyze *ira, IrInst* source_instructi
24522 }16478 }
24523 }16479 }
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)
24526 || type_requires_comptime(ira->codegen, union_type) == ReqCompTimeYes;16482 || type_requires_comptime(ira->codegen, union_type) == ReqCompTimeYes;
2452716483
24528 IrInstGen *result = ir_get_deref(ira, source_instruction, result_loc, nullptr);16484 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...@@ -24575,7 +16531,7 @@ static IrInstGen *ir_analyze_container_init_fields(IrAnalyze *ira, IrInst *sourc
24575 AstNode **field_assign_nodes = heap::c_allocator.allocate<AstNode *>(actual_field_count);16531 AstNode **field_assign_nodes = heap::c_allocator.allocate<AstNode *>(actual_field_count);
24576 ZigList<IrInstGen *> const_ptrs = {};16532 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)
24579 || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes;16535 || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes;
2458016536
2458116537
...@@ -24762,7 +16718,7 @@ static IrInstGen *ir_analyze_instruction_container_init_list(IrAnalyze *ira,...@@ -24762,7 +16718,7 @@ static IrInstGen *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
24762 case ReqCompTimeInvalid:16718 case ReqCompTimeInvalid:
24763 return ira->codegen->invalid_inst_gen;16719 return ira->codegen->invalid_inst_gen;
24764 case ReqCompTimeNo:16720 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);
24766 break;16722 break;
24767 case ReqCompTimeYes:16723 case ReqCompTimeYes:
24768 is_comptime = true;16724 is_comptime = true;
...@@ -26534,7 +18490,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI...@@ -26534,7 +18490,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
2653418490
26535 Buf *bare_name = buf_alloc();18491 Buf *bare_name = buf_alloc();
26536 Buf *full_name = get_anon_type_name(ira->codegen,18492 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);
26538 return get_opaque_type(ira->codegen,18494 return get_opaque_type(ira->codegen,
26539 source_instr->scope, source_instr->source_node, buf_ptr(full_name), bare_name);18495 source_instr->scope, source_instr->source_node, buf_ptr(full_name), bare_name);
26540 }18496 }
...@@ -26581,7 +18537,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI...@@ -26581,7 +18537,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
26581 assert(is_slice(slice->type));18537 assert(is_slice(slice->type));
26582 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet);18538 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet);
26583 Buf bare_name = BUF_INIT;18539 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));
26585 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits;18541 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits;
26586 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align;18542 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align;
26587 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size;18543 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...@@ -26660,7 +18616,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
2666018616
26661 ZigType *entry = new_type_table_entry(ZigTypeIdStruct);18617 ZigType *entry = new_type_table_entry(ZigTypeIdStruct);
26662 buf_init_from_buf(&entry->name,18618 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));
26664 entry->data.structure.decl_node = source_instr->source_node;18620 entry->data.structure.decl_node = source_instr->source_node;
26665 entry->data.structure.fields = alloc_type_struct_fields(fields_len);18621 entry->data.structure.fields = alloc_type_struct_fields(fields_len);
26666 entry->data.structure.fields_by_name.init(fields_len);18622 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...@@ -26770,7 +18726,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
2677018726
26771 ZigType *entry = new_type_table_entry(ZigTypeIdEnum);18727 ZigType *entry = new_type_table_entry(ZigTypeIdEnum);
26772 buf_init_from_buf(&entry->name,18728 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));
26774 entry->data.enumeration.decl_node = source_instr->source_node;18730 entry->data.enumeration.decl_node = source_instr->source_node;
26775 entry->data.enumeration.tag_int_type = tag_type;18731 entry->data.enumeration.tag_int_type = tag_type;
26776 entry->data.enumeration.decls_scope = create_decls_scope(18732 entry->data.enumeration.decls_scope = create_decls_scope(
...@@ -26852,7 +18808,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI...@@ -26852,7 +18808,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
2685218808
26853 ZigType *entry = new_type_table_entry(ZigTypeIdUnion);18809 ZigType *entry = new_type_table_entry(ZigTypeIdUnion);
26854 buf_init_from_buf(&entry->name,18810 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));
26856 entry->data.unionation.decl_node = source_instr->source_node;18812 entry->data.unionation.decl_node = source_instr->source_node;
26857 entry->data.unionation.fields = heap::c_allocator.allocate<TypeUnionField>(fields_len);18813 entry->data.unionation.fields = heap::c_allocator.allocate<TypeUnionField>(fields_len);
26858 entry->data.unionation.fields_by_name.init(fields_len);18814 entry->data.unionation.fields_by_name.init(fields_len);
...@@ -27022,8 +18978,8 @@ static IrInstGen *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ira,...@@ -27022,8 +18978,8 @@ static IrInstGen *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ira,
27022 if (!ir_resolve_unsigned(ira, instruction->new_quota->child, ira->codegen->builtin_types.entry_u32, &new_quota))18978 if (!ir_resolve_unsigned(ira, instruction->new_quota->child, ira->codegen->builtin_types.entry_u32, &new_quota))
27023 return ira->codegen->invalid_inst_gen;18979 return ira->codegen->invalid_inst_gen;
2702418980
27025 if (new_quota > *ira->new_irb.exec->backward_branch_quota) {18981 if (new_quota > *ira->backward_branch_quota) {
27026 *ira->new_irb.exec->backward_branch_quota = new_quota;18982 *ira->backward_branch_quota = new_quota;
27027 }18983 }
2702818984
27029 return ir_const_void(ira, &instruction->base.base);18985 return ir_const_void(ira, &instruction->base.base);
...@@ -27057,7 +19013,7 @@ static IrInstGen *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstSrcCImpo...@@ -27057,7 +19013,7 @@ static IrInstGen *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstSrcCImpo
27057 ZigValue *result_ptr;19013 ZigValue *result_ptr;
27058 create_result_ptr(ira->codegen, void_type, &cimport_result, &result_ptr);19014 create_result_ptr(ira->codegen, void_type, &cimport_result, &result_ptr);
27059 if ((err = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, result_ptr,19015 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,
27061 &cimport_scope->buf, block_node, nullptr, nullptr, nullptr, UndefBad)))19017 &cimport_scope->buf, block_node, nullptr, nullptr, nullptr, UndefBad)))
27062 {19018 {
27063 return ira->codegen->invalid_inst_gen;19019 return ira->codegen->invalid_inst_gen;
...@@ -27066,8 +19022,10 @@ static IrInstGen *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstSrcCImpo...@@ -27066,8 +19022,10 @@ static IrInstGen *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstSrcCImpo
27066 return ira->codegen->invalid_inst_gen;19022 return ira->codegen->invalid_inst_gen;
2706719023
27068 ZigPackage *cur_scope_pkg = scope_package(instruction->base.base.scope);19024 ZigPackage *cur_scope_pkg = scope_package(instruction->base.base.scope);
27069 Buf *namespace_name = buf_sprintf("%s.cimport:%" ZIG_PRI_usize ":%" ZIG_PRI_usize,19025 RootStruct *root_struct = node->owner->data.structure.root_struct;
27070 buf_ptr(&cur_scope_pkg->pkg_path), node->line + 1, node->column + 1);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
27072 ZigPackage *cimport_pkg = new_anonymous_package();19030 ZigPackage *cimport_pkg = new_anonymous_package();
27073 cimport_pkg->package_table.put(buf_create_from_str("builtin"), ira->codegen->compile_var_package);19031 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...@@ -27095,12 +19053,14 @@ static IrInstGen *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstSrcCImpo
27095 }19053 }
27096 for (size_t i = 0; i < errors_len; i += 1) {19054 for (size_t i = 0; i < errors_len; i += 1) {
27097 Stage2ErrorMsg *clang_err = &errors_ptr[i];19055 Stage2ErrorMsg *clang_err = &errors_ptr[i];
27098 // Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null19056 // Clang can emit "too many errors, stopping now", in which case
19057 // `source` and `filename_ptr` are null
27099 if (clang_err->source && clang_err->filename_ptr) {19058 if (clang_err->source && clang_err->filename_ptr) {
27100 ErrorMsg *err_msg = err_msg_create_with_offset(19059 ErrorMsg *err_msg = err_msg_create_with_offset(
27101 clang_err->filename_ptr ?19060 clang_err->filename_ptr ?
27102 buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(),19061 buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) :
27103 clang_err->line, clang_err->column, clang_err->offset, clang_err->source,19062 buf_alloc(),
19063 clang_err->offset, clang_err->source,
27104 buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len));19064 buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len));
27105 err_msg_add_note(parent_err_msg, err_msg);19065 err_msg_add_note(parent_err_msg, err_msg);
27106 }19066 }
...@@ -27225,7 +19185,7 @@ static IrInstGen *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstSrcEmb...@@ -27225,7 +19185,7 @@ static IrInstGen *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstSrcEmb
27225 }19185 }
2722619186
27227 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);19187 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);
27229 return result;19189 return result;
27230}19190}
2723119191
...@@ -29108,7 +21068,7 @@ static IrInstGen *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrInstSrc...@@ -29108,7 +21068,7 @@ static IrInstGen *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrInstSrc
29108}21068}
2910921069
29110static IrInstGen *ir_analyze_instruction_frame_handle(IrAnalyze *ira, IrInstSrcFrameHandle *instruction) {21070static IrInstGen *ir_analyze_instruction_frame_handle(IrAnalyze *ira, IrInstSrcFrameHandle *instruction) {
29111 ZigFn *fn = ira->new_irb.exec->fn_entry;21071 ZigFn *fn = ira->fn;
29112 ir_assert(fn != nullptr, &instruction->base.base);21072 ir_assert(fn != nullptr, &instruction->base.base);
2911321073
29114 if (fn->inferred_async_node == nullptr) {21074 if (fn->inferred_async_node == nullptr) {
...@@ -30043,7 +22003,7 @@ static IrInstGen *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstSrcPanic *i...@@ -30043,7 +22003,7 @@ static IrInstGen *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstSrcPanic *i
30043 if (type_is_invalid(msg->value->type))22003 if (type_is_invalid(msg->value->type))
30044 return ir_unreach_error(ira);22004 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)) {
30047 ir_add_error(ira, &instruction->base.base, buf_sprintf("encountered @panic at compile-time"));22007 ir_add_error(ira, &instruction->base.base, buf_sprintf("encountered @panic at compile-time"));
30048 return ir_unreach_error(ira);22008 return ir_unreach_error(ira);
30049 }22009 }
...@@ -30971,7 +22931,7 @@ static IrInstGen *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, IrInstS...@@ -30971,7 +22931,7 @@ static IrInstGen *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, IrInstS
30971 return ira->codegen->invalid_inst_gen;22931 return ira->codegen->invalid_inst_gen;
30972 }22932 }
3097322933
30974 ZigFn *fn_entry = ira->new_irb.exec->fn_entry;22934 ZigFn *fn_entry = ira->fn;
30975 if (fn_entry == nullptr) {22935 if (fn_entry == nullptr) {
30976 ir_add_error(ira, &instruction->base.base, buf_sprintf("@setAlignStack outside function"));22936 ir_add_error(ira, &instruction->base.base, buf_sprintf("@setAlignStack outside function"));
30977 return ira->codegen->invalid_inst_gen;22937 return ira->codegen->invalid_inst_gen;
...@@ -31851,6 +23811,22 @@ static IrInstGen *ir_analyze_instruction_has_decl(IrAnalyze *ira, IrInstSrcHasDe...@@ -31851,6 +23811,22 @@ static IrInstGen *ir_analyze_instruction_has_decl(IrAnalyze *ira, IrInstSrcHasDe
31851 return ir_const_bool(ira, &instruction->base.base, true);23811 return ir_const_bool(ira, &instruction->base.base, true);
31852}23812}
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
31854static IrInstGen *ir_analyze_instruction_undeclared_ident(IrAnalyze *ira, IrInstSrcUndeclaredIdent *instruction) {23830static IrInstGen *ir_analyze_instruction_undeclared_ident(IrAnalyze *ira, IrInstSrcUndeclaredIdent *instruction) {
31855 // put a variable of same name with invalid type in global scope23831 // put a variable of same name with invalid type in global scope
31856 // so that future references to this same name will find a variable with an invalid type23832 // 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...@@ -31975,7 +23951,7 @@ static IrInstGen *ir_analyze_instruction_suspend_finish(IrAnalyze *ira, IrInstSr
31975 ir_assert(begin_base->id == IrInstGenIdSuspendBegin, &instruction->base.base);23951 ir_assert(begin_base->id == IrInstGenIdSuspendBegin, &instruction->base.base);
31976 IrInstGenSuspendBegin *begin = reinterpret_cast<IrInstGenSuspendBegin *>(begin_base);23952 IrInstGenSuspendBegin *begin = reinterpret_cast<IrInstGenSuspendBegin *>(begin_base);
3197723953
31978 ZigFn *fn_entry = ira->new_irb.exec->fn_entry;23954 ZigFn *fn_entry = ira->fn;
31979 ir_assert(fn_entry != nullptr, &instruction->base.base);23955 ir_assert(fn_entry != nullptr, &instruction->base.base);
3198023956
31981 if (fn_entry->inferred_async_node == nullptr) {23957 if (fn_entry->inferred_async_node == nullptr) {
...@@ -32042,7 +24018,7 @@ static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *i...@@ -32042,7 +24018,7 @@ static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *i
3204224018
32043 ZigType *result_type = frame->value->type->data.any_frame.result_type;24019 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;
32046 ir_assert(fn_entry != nullptr, &instruction->base.base);24022 ir_assert(fn_entry != nullptr, &instruction->base.base);
3204724023
32048 // If it's not @Frame(func) then it's definitely a suspend point24024 // 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...@@ -32100,7 +24076,7 @@ static IrInstGen *ir_analyze_instruction_resume(IrAnalyze *ira, IrInstSrcResume
32100}24076}
3210124077
32102static IrInstGen *ir_analyze_instruction_spill_begin(IrAnalyze *ira, IrInstSrcSpillBegin *instruction) {24078static 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))
32104 return ir_const_void(ira, &instruction->base.base);24080 return ir_const_void(ira, &instruction->base.base);
3210524081
32106 IrInstGen *operand = instruction->operand->child;24082 IrInstGen *operand = instruction->operand->child;
...@@ -32126,7 +24102,7 @@ static IrInstGen *ir_analyze_instruction_spill_end(IrAnalyze *ira, IrInstSrcSpil...@@ -32126,7 +24102,7 @@ static IrInstGen *ir_analyze_instruction_spill_end(IrAnalyze *ira, IrInstSrcSpil
32126 if (type_is_invalid(operand->value->type))24102 if (type_is_invalid(operand->value->type))
32127 return ira->codegen->invalid_inst_gen;24103 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) ||
32130 !type_has_bits(ira->codegen, operand->value->type) ||24106 !type_has_bits(ira->codegen, operand->value->type) ||
32131 instr_is_comptime(operand))24107 instr_is_comptime(operand))
32132 {24108 {
...@@ -32169,7 +24145,8 @@ static IrInstGen *ir_analyze_instruction_src(IrAnalyze *ira, IrInstSrcSrc *instr...@@ -32169,7 +24145,8 @@ static IrInstGen *ir_analyze_instruction_src(IrAnalyze *ira, IrInstSrcSrc *instr
32169 fields[0]->special = ConstValSpecialStatic;24145 fields[0]->special = ConstValSpecialStatic;
3217024146
32171 ZigType *import = instruction->base.base.source_node->owner;24147 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;
32173 ZigValue *file_name = create_const_str_lit(ira->codegen, path)->data.x_ptr.data.ref.pointee;24150 ZigValue *file_name = create_const_str_lit(ira->codegen, path)->data.x_ptr.data.ref.pointee;
32174 init_const_slice(ira->codegen, fields[0], file_name, 0, buf_len(path), true);24151 init_const_slice(ira->codegen, fields[0], file_name, 0, buf_len(path), true);
32175 fields[0]->type = u8_slice;24152 fields[0]->type = u8_slice;
...@@ -32182,17 +24159,20 @@ static IrInstGen *ir_analyze_instruction_src(IrAnalyze *ira, IrInstSrcSrc *instr...@@ -32182,17 +24159,20 @@ static IrInstGen *ir_analyze_instruction_src(IrAnalyze *ira, IrInstSrcSrc *instr
32182 init_const_slice(ira->codegen, fields[1], fn_name, 0, buf_len(&fn_entry->symbol_name), true);24159 init_const_slice(ira->codegen, fields[1], fn_name, 0, buf_len(&fn_entry->symbol_name), true);
32183 fields[1]->type = u8_slice;24160 fields[1]->type = u8_slice;
3218424161
24162
24163 TokenLoc tok_loc = root_struct->token_locs[instruction->base.base.source_node->main_token];
24164
32185 // line: u3224165 // line: u32
32186 ensure_field_index(source_location_type, "line", 2);24166 ensure_field_index(source_location_type, "line", 2);
32187 fields[2]->special = ConstValSpecialStatic;24167 fields[2]->special = ConstValSpecialStatic;
32188 fields[2]->type = ira->codegen->builtin_types.entry_u32;24168 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
32191 // column: u3224171 // column: u32
32192 ensure_field_index(source_location_type, "column", 3);24172 ensure_field_index(source_location_type, "column", 3);
32193 fields[3]->special = ConstValSpecialStatic;24173 fields[3]->special = ConstValSpecialStatic;
32194 fields[3]->type = ira->codegen->builtin_types.entry_u32;24174 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
32197 return ir_const_move(ira, &instruction->base.base, result);24177 return ir_const_move(ira, &instruction->base.base, result);
32198}24178}
...@@ -32484,29 +24464,31 @@ static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruc...@@ -32484,29 +24464,31 @@ static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruc
32484 zig_unreachable();24464 zig_unreachable();
32485}24465}
3248624466
32487// This function attempts to evaluate IR code while doing type checking and other analysis.24467// This function attempts to evaluate stage1 ZIR code while doing type checking and other analysis.
32488// It emits to a new IrExecutableGen which is partially evaluated IR code.24468// It emits to a new Stage1Air which is partially evaluated IR code.
32489ZigType *ir_analyze(CodeGen *codegen, IrExecutableSrc *old_exec, IrExecutableGen *new_exec,24469ZigType *ir_analyze(CodeGen *codegen, Stage1Zir *stage1_zir, Stage1Air *stage1_air,
32490 ZigType *expected_type, AstNode *expected_type_source_node, ZigValue *result_ptr)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)
32491{24472{
32492 assert(old_exec->first_err_trace_msg == nullptr);24473 assert(stage1_zir->first_err_trace_msg == nullptr);
32493 assert(expected_type == nullptr || !type_is_invalid(expected_type));24474 assert(expected_type == nullptr || !type_is_invalid(expected_type));
3249424475
32495 IrAnalyze *ira = heap::c_allocator.create<IrAnalyze>();24476 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;
32496 ira->ref_count = 1;24480 ira->ref_count = 1;
32497 old_exec->analysis = ira;
32498 ira->codegen = codegen;24481 ira->codegen = codegen;
3249924482
32500 ira->explicit_return_type = expected_type;24483 ira->explicit_return_type = expected_type;
32501 ira->explicit_return_type_source_node = expected_type_source_node;24484 ira->explicit_return_type_source_node = expected_type_source_node;
3250224485
32503 ira->old_irb.codegen = codegen;24486 ira->zir = stage1_zir;
32504 ira->old_irb.exec = old_exec;
3250524487
32506 ira->new_irb.codegen = codegen;24488 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);
32510 IrBasicBlockGen *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr);24492 IrBasicBlockGen *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr);
32511 ira->new_irb.current_basic_block = new_entry_bb;24493 ira->new_irb.current_basic_block = new_entry_bb;
32512 ira->old_bb_index = 0;24494 ira->old_bb_index = 0;
...@@ -32516,18 +24498,18 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutableSrc *old_exec, IrExecutableGen...@@ -32516,18 +24498,18 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutableSrc *old_exec, IrExecutableGen
32516 if (result_ptr != nullptr) {24498 if (result_ptr != nullptr) {
32517 assert(result_ptr->type->id == ZigTypeIdPointer);24499 assert(result_ptr->type->id == ZigTypeIdPointer);
32518 IrInstGenConst *const_inst = ir_create_inst_noval<IrInstGenConst>(24500 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);
32520 const_inst->base.value = result_ptr;24502 const_inst->base.value = result_ptr;
32521 ira->return_ptr = &const_inst->base;24503 ira->return_ptr = &const_inst->base;
32522 } else {24504 } else {
32523 assert(new_exec->begin_scope != nullptr);24505 assert(stage1_air->begin_scope != nullptr);
32524 assert(new_exec->source_node != nullptr);24506 assert(stage1_air->source_node != nullptr);
32525 ira->return_ptr = ir_build_return_ptr(ira, new_exec->begin_scope, new_exec->source_node,24507 ira->return_ptr = ir_build_return_ptr(ira, stage1_air->begin_scope, stage1_air->source_node,
32526 get_pointer_to_type(codegen, expected_type, false));24508 get_pointer_to_type(codegen, expected_type, false));
32527 }24509 }
3252824510
32529 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) {24511 while (ira->old_bb_index < ira->zir->basic_block_list.length) {
32530 IrInstSrc *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index);24512 IrInstSrc *old_instruction = ira->zir_current_basic_block->instruction_list.at(ira->instruction_index);
3253124513
32532 if (old_instruction->base.ref_count == 0 && !ir_inst_src_has_side_effects(old_instruction)) {24514 if (old_instruction->base.ref_count == 0 && !ir_inst_src_has_side_effects(old_instruction)) {
32533 ira->instruction_index += 1;24515 ira->instruction_index += 1;
...@@ -32539,20 +24521,6 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutableSrc *old_exec, IrExecutableGen...@@ -32539,20 +24521,6 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutableSrc *old_exec, IrExecutableGen
32539 old_instruction->src();24521 old_instruction->src();
32540 fprintf(stderr, "~ ");24522 fprintf(stderr, "~ ");
32541 ir_print_inst_src(codegen, stderr, old_instruction, 0);24523 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;
32556 }24524 }
32557 IrInstGen *new_instruction = ir_analyze_instruction_base(ira, old_instruction);24525 IrInstGen *new_instruction = ir_analyze_instruction_base(ira, old_instruction);
32558 if (new_instruction != nullptr) {24526 if (new_instruction != nullptr) {
...@@ -32564,16 +24532,16 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutableSrc *old_exec, IrExecutableGen...@@ -32564,16 +24532,16 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutableSrc *old_exec, IrExecutableGen
32564 fprintf(stderr, "-> (invalid)");24532 fprintf(stderr, "-> (invalid)");
32565 }24533 }
3256624534
32567 if (new_exec->first_err_trace_msg != nullptr) {24535 if (stage1_air->first_err_trace_msg != nullptr) {
32568 ira->codegen->trace_err = new_exec->first_err_trace_msg;24536 ira->codegen->trace_err = stage1_air->first_err_trace_msg;
32569 } else {24537 } else {
32570 new_exec->first_err_trace_msg = ira->codegen->trace_err;24538 stage1_air->first_err_trace_msg = ira->codegen->trace_err;
32571 }24539 }
32572 if (new_exec->first_err_trace_msg != nullptr &&24540 if (stage1_air->first_err_trace_msg != nullptr &&
32573 !old_instruction->base.source_node->already_traced_this_node)24541 !old_instruction->base.source_node->already_traced_this_node)
32574 {24542 {
32575 old_instruction->base.source_node->already_traced_this_node = true;24543 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,
32577 old_instruction->base.source_node, buf_create_from_str("referenced here"));24545 old_instruction->base.source_node, buf_create_from_str("referenced here"));
32578 }24546 }
32579 return ira->codegen->builtin_types.entry_invalid;24547 return ira->codegen->builtin_types.entry_invalid;
...@@ -32599,14 +24567,14 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutableSrc *old_exec, IrExecutableGen...@@ -32599,14 +24567,14 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutableSrc *old_exec, IrExecutableGen
32599 }24567 }
3260024568
32601 ZigType *res_type;24569 ZigType *res_type;
32602 if (new_exec->first_err_trace_msg != nullptr) {24570 if (stage1_air->first_err_trace_msg != nullptr) {
32603 codegen->trace_err = new_exec->first_err_trace_msg;24571 codegen->trace_err = stage1_air->first_err_trace_msg;
32604 if (codegen->trace_err != nullptr && new_exec->source_node != nullptr &&24572 if (codegen->trace_err != nullptr && stage1_air->source_node != nullptr &&
32605 !new_exec->source_node->already_traced_this_node)24573 !stage1_air->source_node->already_traced_this_node)
32606 {24574 {
32607 new_exec->source_node->already_traced_this_node = true;24575 stage1_air->source_node->already_traced_this_node = true;
32608 codegen->trace_err = add_error_note(codegen, codegen->trace_err,24576 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"));
32610 }24578 }
32611 res_type = ira->codegen->builtin_types.entry_invalid;24579 res_type = ira->codegen->builtin_types.entry_invalid;
32612 } else if (ira->src_implicit_return_type_list.length == 0) {24580 } else if (ira->src_implicit_return_type_list.length == 0) {
...@@ -33541,11 +25509,3 @@ void IrAnalyze::dump() {...@@ -33541,11 +25509,3 @@ void IrAnalyze::dump() {
33541 ir_print_basic_block_gen(this->codegen, stderr, this->new_irb.current_basic_block, 1);25509 ir_print_basic_block_gen(this->codegen, stderr, this->new_irb.current_basic_block, 1);
33542 }25510 }
33543}25511}
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 @@...@@ -10,31 +10,25 @@
1010
11#include "all_types.hpp"11#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
16IrInstGen *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node, ZigFn *fn,13IrInstGen *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node, ZigFn *fn,
17 ZigType *var_type, const char *name_hint);14 ZigType *var_type, const char *name_hint);
1815
19Error ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,16Error ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
20 ZigValue *return_ptr, size_t *backward_branch_count, size_t *backward_branch_quota,17 ZigValue *return_ptr, size_t *backward_branch_count, size_t *backward_branch_quota,
21 ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name,18 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
24Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ZigValue *val);21Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ZigValue *val);
2522
26ZigType *ir_analyze(CodeGen *g, IrExecutableSrc *old_executable, IrExecutableGen *new_executable,23ZigType *ir_analyze(CodeGen *codegen, Stage1Zir *stage1_zir, Stage1Air *stage1_air,
27 ZigType *expected_type, AstNode *expected_type_source_node, ZigValue *return_ptr);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
29bool ir_inst_gen_has_side_effects(IrInstGen *inst);28bool ir_inst_gen_has_side_effects(IrInstGen *inst);
30bool ir_inst_src_has_side_effects(IrInstSrc *inst);
3129
32struct IrAnalyze;30struct IrAnalyze;
33ZigValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ZigValue *const_val,31ZigValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ZigValue *const_val,
34 AstNode *source_node);32 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
40#endif34#endif
src/stage1/ir_print.cpp+7-6
...@@ -8,6 +8,7 @@...@@ -8,6 +8,7 @@
8#include "all_types.hpp"8#include "all_types.hpp"
9#include "analyze.hpp"9#include "analyze.hpp"
10#include "ir.hpp"10#include "ir.hpp"
11#include "astgen.hpp"
11#include "ir_print.hpp"12#include "ir_print.hpp"
12#include "os.hpp"13#include "os.hpp"
1314
...@@ -632,7 +633,7 @@ static void ir_print_other_inst_gen(IrPrintGen *irp, IrInstGen *inst) {...@@ -632,7 +633,7 @@ static void ir_print_other_inst_gen(IrPrintGen *irp, IrInstGen *inst) {
632 }633 }
633}634}
634635
635static void ir_print_other_block(IrPrintSrc *irp, IrBasicBlockSrc *bb) {636static void ir_print_other_block(IrPrintSrc *irp, Stage1ZirBasicBlock *bb) {
636 if (bb == nullptr) {637 if (bb == nullptr) {
637 fprintf(irp->f, "(null block)");638 fprintf(irp->f, "(null block)");
638 } else {639 } else {
...@@ -1005,7 +1006,7 @@ static void ir_print_phi(IrPrintSrc *irp, IrInstSrcPhi *phi_instruction) {...@@ -1005,7 +1006,7 @@ static void ir_print_phi(IrPrintSrc *irp, IrInstSrcPhi *phi_instruction) {
1005 assert(phi_instruction->incoming_count != 0);1006 assert(phi_instruction->incoming_count != 0);
1006 assert(phi_instruction->incoming_count != SIZE_MAX);1007 assert(phi_instruction->incoming_count != SIZE_MAX);
1007 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) {1008 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];
1009 IrInstSrc *incoming_value = phi_instruction->incoming_values[i];1010 IrInstSrc *incoming_value = phi_instruction->incoming_values[i];
1010 if (i != 0)1011 if (i != 0)
1011 fprintf(irp->f, " ");1012 fprintf(irp->f, " ");
...@@ -3349,7 +3350,7 @@ static void ir_print_inst_gen(IrPrintGen *irp, IrInstGen *instruction, bool trai...@@ -3349,7 +3350,7 @@ static void ir_print_inst_gen(IrPrintGen *irp, IrInstGen *instruction, bool trai
3349 fprintf(irp->f, "\n");3350 fprintf(irp->f, "\n");
3350}3351}
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) {
3353 fprintf(irp->f, "%s_%" PRIu32 ":\n", current_block->name_hint, current_block->debug_id);3354 fprintf(irp->f, "%s_%" PRIu32 ":\n", current_block->name_hint, current_block->debug_id);
3354 for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) {3355 for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) {
3355 IrInstSrc *instruction = current_block->instruction_list.at(instr_i);3356 IrInstSrc *instruction = current_block->instruction_list.at(instr_i);
...@@ -3369,7 +3370,7 @@ static void irp_print_basic_block_gen(IrPrintGen *irp, IrBasicBlockGen *current_...@@ -3369,7 +3370,7 @@ static void irp_print_basic_block_gen(IrPrintGen *irp, IrBasicBlockGen *current_
3369 }3370 }
3370}3371}
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) {
3373 IrPrintSrc ir_print = {};3374 IrPrintSrc ir_print = {};
3374 ir_print.codegen = codegen;3375 ir_print.codegen = codegen;
3375 ir_print.f = f;3376 ir_print.f = f;
...@@ -3395,7 +3396,7 @@ void ir_print_basic_block_gen(CodeGen *codegen, FILE *f, IrBasicBlockGen *bb, in...@@ -3395,7 +3396,7 @@ void ir_print_basic_block_gen(CodeGen *codegen, FILE *f, IrBasicBlockGen *bb, in
3395 ir_print.printed.deinit();3396 ir_print.printed.deinit();
3396}3397}
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) {
3399 IrPrintSrc ir_print = {};3400 IrPrintSrc ir_print = {};
3400 IrPrintSrc *irp = &ir_print;3401 IrPrintSrc *irp = &ir_print;
3401 irp->codegen = codegen;3402 irp->codegen = codegen;
...@@ -3408,7 +3409,7 @@ void ir_print_src(CodeGen *codegen, FILE *f, IrExecutableSrc *executable, int in...@@ -3408,7 +3409,7 @@ void ir_print_src(CodeGen *codegen, FILE *f, IrExecutableSrc *executable, int in
3408 }3409 }
3409}3410}
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) {
3412 IrPrintGen ir_print = {};3413 IrPrintGen ir_print = {};
3413 IrPrintGen *irp = &ir_print;3414 IrPrintGen *irp = &ir_print;
3414 irp->codegen = codegen;3415 irp->codegen = codegen;
src/stage1/ir_print.hpp+3-3
...@@ -12,11 +12,11 @@...@@ -12,11 +12,11 @@
1212
13#include <stdio.h>13#include <stdio.h>
1414
15void ir_print_src(CodeGen *codegen, FILE *f, IrExecutableSrc *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, IrExecutableGen *executable, int indent_size);16void ir_print_gen(CodeGen *codegen, FILE *f, Stage1Air *executable, int indent_size);
17void ir_print_inst_src(CodeGen *codegen, FILE *f, IrInstSrc *inst, int indent_size);17void ir_print_inst_src(CodeGen *codegen, FILE *f, IrInstSrc *inst, int indent_size);
18void ir_print_inst_gen(CodeGen *codegen, FILE *f, IrInstGen *inst, int indent_size);18void 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);
20void ir_print_basic_block_gen(CodeGen *codegen, FILE *f, IrBasicBlockGen *bb, int indent_size);20void ir_print_basic_block_gen(CodeGen *codegen, FILE *f, IrBasicBlockGen *bb, int indent_size);
2121
22const char* ir_inst_src_type_str(IrInstSrcId id);22const char* ir_inst_src_type_str(IrInstSrcId id);
src/stage1/parser.cpp+921-593
...@@ -16,28 +16,34 @@...@@ -16,28 +16,34 @@
1616
17struct ParseContext {17struct ParseContext {
18 Buf *buf;18 Buf *buf;
19 size_t current_token;19 // Shortcut to `owner->data.structure.root_struct->token_ids`.
20 ZigList<Token> *tokens;20 TokenId *token_ids;
21 // Shortcut to `owner->data.structure.root_struct->token_locs`.
22 TokenLoc *token_locs;
21 ZigType *owner;23 ZigType *owner;
24 TokenIndex current_token;
22 ErrColor err_color;25 ErrColor err_color;
26 // Shortcut to `owner->data.structure.root_struct->token_count`.
27 uint32_t token_count;
23};28};
2429
25struct PtrPayload {30struct PtrPayload {
26 Token *asterisk;31 TokenIndex asterisk;
27 Token *payload;32 TokenIndex payload;
28};33};
2934
30struct PtrIndexPayload {35struct PtrIndexPayload {
31 Token *asterisk;36 TokenIndex asterisk;
32 Token *payload;37 TokenIndex payload;
33 Token *index;38 TokenIndex index;
34};39};
3540
36static AstNode *ast_parse_root(ParseContext *pc);41static AstNode *ast_parse_root(ParseContext *pc);
37static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc);42static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc);
38static AstNode *ast_parse_test_decl(ParseContext *pc);43static AstNode *ast_parse_test_decl(ParseContext *pc);
39static AstNode *ast_parse_top_level_comptime(ParseContext *pc);44static 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);
41static AstNode *ast_parse_fn_proto(ParseContext *pc);47static AstNode *ast_parse_fn_proto(ParseContext *pc);
42static AstNode *ast_parse_var_decl(ParseContext *pc);48static AstNode *ast_parse_var_decl(ParseContext *pc);
43static AstNode *ast_parse_container_field(ParseContext *pc);49static AstNode *ast_parse_container_field(ParseContext *pc);
...@@ -87,8 +93,8 @@ static AsmOutput *ast_parse_asm_output_item(ParseContext *pc);...@@ -87,8 +93,8 @@ static AsmOutput *ast_parse_asm_output_item(ParseContext *pc);
87static AstNode *ast_parse_asm_input(ParseContext *pc);93static AstNode *ast_parse_asm_input(ParseContext *pc);
88static AsmInput *ast_parse_asm_input_item(ParseContext *pc);94static AsmInput *ast_parse_asm_input_item(ParseContext *pc);
89static AstNode *ast_parse_asm_clobbers(ParseContext *pc);95static AstNode *ast_parse_asm_clobbers(ParseContext *pc);
90static Token *ast_parse_break_label(ParseContext *pc);96static TokenIndex ast_parse_break_label(ParseContext *pc);
91static Token *ast_parse_block_label(ParseContext *pc);97static TokenIndex ast_parse_block_label(ParseContext *pc);
92static AstNode *ast_parse_field_init(ParseContext *pc);98static AstNode *ast_parse_field_init(ParseContext *pc);
93static AstNode *ast_parse_while_continue_expr(ParseContext *pc);99static AstNode *ast_parse_while_continue_expr(ParseContext *pc);
94static AstNode *ast_parse_link_section(ParseContext *pc);100static AstNode *ast_parse_link_section(ParseContext *pc);
...@@ -98,7 +104,7 @@ static AstNode *ast_parse_param_type(ParseContext *pc);...@@ -98,7 +104,7 @@ static AstNode *ast_parse_param_type(ParseContext *pc);
98static AstNode *ast_parse_if_prefix(ParseContext *pc);104static AstNode *ast_parse_if_prefix(ParseContext *pc);
99static AstNode *ast_parse_while_prefix(ParseContext *pc);105static AstNode *ast_parse_while_prefix(ParseContext *pc);
100static AstNode *ast_parse_for_prefix(ParseContext *pc);106static AstNode *ast_parse_for_prefix(ParseContext *pc);
101static Token *ast_parse_payload(ParseContext *pc);107static TokenIndex ast_parse_payload(ParseContext *pc);
102static Optional<PtrPayload> ast_parse_ptr_payload(ParseContext *pc);108static Optional<PtrPayload> ast_parse_ptr_payload(ParseContext *pc);
103static Optional<PtrIndexPayload> ast_parse_ptr_index_payload(ParseContext *pc);109static Optional<PtrIndexPayload> ast_parse_ptr_index_payload(ParseContext *pc);
104static AstNode *ast_parse_switch_prong(ParseContext *pc);110static AstNode *ast_parse_switch_prong(ParseContext *pc);
...@@ -120,29 +126,34 @@ static AstNode *ast_parse_container_decl_auto(ParseContext *pc);...@@ -120,29 +126,34 @@ static AstNode *ast_parse_container_decl_auto(ParseContext *pc);
120static AstNode *ast_parse_container_decl_type(ParseContext *pc);126static AstNode *ast_parse_container_decl_type(ParseContext *pc);
121static AstNode *ast_parse_byte_align(ParseContext *pc);127static 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
123ATTRIBUTE_PRINTF(3, 4)142ATTRIBUTE_PRINTF(3, 4)
124ATTRIBUTE_NORETURN143ATTRIBUTE_NORETURN
125static void ast_error(ParseContext *pc, Token *token, const char *format, ...) {144static void ast_error(ParseContext *pc, TokenIndex token, const char *format, ...) {
126 va_list ap;145 va_list ap;
127 va_start(ap, format);146 va_start(ap, format);
128 Buf *msg = buf_vprintf(format, ap);147 Buf *msg = buf_vprintf(format, ap);
129 va_end(ap);148 va_end(ap);
130149
131150 RootStruct *root_struct = pc->owner->data.structure.root_struct;
132 ErrorMsg *err = err_msg_create_with_line(pc->owner->data.structure.root_struct->path,151 ast_error_offset(root_struct, pc->err_color, token, 0, msg);
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);
141}152}
142153
143ATTRIBUTE_NORETURN154ATTRIBUTE_NORETURN
144static void ast_invalid_token_error(ParseContext *pc, Token *token) {155static void ast_invalid_token_error(ParseContext *pc, TokenIndex token) {
145 ast_error(pc, token, "invalid token: '%s'", token_name(token->id));156 ast_error(pc, token, "invalid token: '%s'", token_name(pc->token_ids[token]));
146}157}
147158
148static AstNode *ast_create_node_no_line_info(ParseContext *pc, NodeType type) {159static 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) {...@@ -152,48 +163,44 @@ static AstNode *ast_create_node_no_line_info(ParseContext *pc, NodeType type) {
152 return node;163 return node;
153}164}
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) {
156 assert(first_token);167 assert(first_token);
157 AstNode *node = ast_create_node_no_line_info(pc, type);168 AstNode *node = ast_create_node_no_line_info(pc, type);
158 node->line = first_token->start_line;169 node->main_token = first_token;
159 node->column = first_token->start_column;
160 return node;170 return node;
161}171}
162172
163static AstNode *ast_create_node_copy_line_info(ParseContext *pc, NodeType type, AstNode *from) {173static AstNode *ast_create_node_copy_line_info(ParseContext *pc, NodeType type, AstNode *from) {
164 assert(from);174 assert(from);
165 AstNode *node = ast_create_node_no_line_info(pc, type);175 AstNode *node = ast_create_node_no_line_info(pc, type);
166 node->line = from->line;176 node->main_token = from->main_token;
167 node->column = from->column;
168 return node;177 return node;
169}178}
170179
171static Token *peek_token_i(ParseContext *pc, size_t i) {180static TokenIndex peek_token(ParseContext *pc) {
172 return &pc->tokens->at(pc->current_token + i);181 return pc->current_token;
173}
174
175static Token *peek_token(ParseContext *pc) {
176 return peek_token_i(pc, 0);
177}182}
178183
179static Token *eat_token(ParseContext *pc) {184static TokenIndex eat_token(ParseContext *pc) {
180 Token *res = peek_token(pc);185 TokenIndex res = peek_token(pc);
181 pc->current_token += 1;186 pc->current_token += 1;
182 return res;187 return res;
183}188}
184189
185static Token *eat_token_if(ParseContext *pc, TokenId id) {190static TokenIndex eat_token_if(ParseContext *pc, TokenId id) {
186 Token *res = peek_token(pc);191 TokenIndex res = peek_token(pc);
187 if (res->id == id)192 if (pc->token_ids[res] == id) {
188 return eat_token(pc);193 return eat_token(pc);
194 }
189195
190 return nullptr;196 return 0;
191}197}
192198
193static Token *expect_token(ParseContext *pc, TokenId id) {199static TokenIndex expect_token(ParseContext *pc, TokenId id) {
194 Token *res = eat_token(pc);200 TokenIndex res = eat_token(pc);
195 if (res->id != id)201 TokenId actual_id = pc->token_ids[res];
196 ast_error(pc, res, "expected token '%s', found '%s'", token_name(id), token_name(res->id));202 if (actual_id != id)
203 ast_error(pc, res, "expected token '%s', found '%s'", token_name(id), token_name(actual_id));
197204
198 return res;205 return res;
199}206}
...@@ -202,23 +209,34 @@ static void put_back_token(ParseContext *pc) {...@@ -202,23 +209,34 @@ static void put_back_token(ParseContext *pc) {
202 pc->current_token -= 1;209 pc->current_token -= 1;
203}210}
204211
205static Buf *token_buf(Token *token) {212static Buf *token_buf(ParseContext *pc, TokenIndex token) {
206 if (token == nullptr)213 Error err;
214
215 if (token == 0)
207 return nullptr;216 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) {218 RootStruct *root_struct = pc->owner->data.structure.root_struct;
213 assert(token->id == TokenIdIntLiteral);219 if (root_struct->token_ids[token] == TokenIdIdentifier) {
214 return &token->data.int_lit.bigint;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 }
215}235}
216236
217static AstNode *token_symbol(ParseContext *pc, Token *token) {237static AstNode *token_identifier(ParseContext *pc, TokenIndex token) {
218 assert(token->id == TokenIdSymbol);238 assert(pc->token_ids[token] == TokenIdIdentifier);
219 AstNode *res = ast_create_node(pc, NodeTypeSymbol, token);239 return ast_create_node(pc, NodeTypeIdentifier, token);
220 res->data.symbol_expr.symbol = token_buf(token);
221 return res;
222}240}
223241
224// (Rule SEP)* Rule?242// (Rule SEP)* Rule?
...@@ -231,7 +249,7 @@ static ZigList<T *> ast_parse_list(ParseContext *pc, TokenId sep, T *(*parser)(P...@@ -231,7 +249,7 @@ static ZigList<T *> ast_parse_list(ParseContext *pc, TokenId sep, T *(*parser)(P
231 break;249 break;
232250
233 res.append(curr);251 res.append(curr);
234 if (eat_token_if(pc, sep) == nullptr)252 if (eat_token_if(pc, sep) == 0)
235 break;253 break;
236 }254 }
237255
...@@ -355,22 +373,22 @@ static AstNode *ast_parse_if_expr_helper(ParseContext *pc, AstNode *(*body_parse...@@ -355,22 +373,22 @@ static AstNode *ast_parse_if_expr_helper(ParseContext *pc, AstNode *(*body_parse
355 return nullptr;373 return nullptr;
356374
357 AstNode *body = ast_expect(pc, body_parser);375 AstNode *body = ast_expect(pc, body_parser);
358 Token *err_payload = nullptr;376 TokenIndex err_payload = 0;
359 AstNode *else_body = nullptr;377 AstNode *else_body = nullptr;
360 if (eat_token_if(pc, TokenIdKeywordElse) != nullptr) {378 if (eat_token_if(pc, TokenIdKeywordElse) != 0) {
361 err_payload = ast_parse_payload(pc);379 err_payload = ast_parse_payload(pc);
362 else_body = ast_expect(pc, body_parser);380 else_body = ast_expect(pc, body_parser);
363 }381 }
364382
365 assert(res->type == NodeTypeIfOptional);383 assert(res->type == NodeTypeIfOptional);
366 if (err_payload != nullptr) {384 if (err_payload != 0) {
367 AstNodeTestExpr old = res->data.test_expr;385 AstNodeTestExpr old = res->data.test_expr;
368 res->type = NodeTypeIfErrorExpr;386 res->type = NodeTypeIfErrorExpr;
369 res->data.if_err_expr.target_node = old.target_node;387 res->data.if_err_expr.target_node = old.target_node;
370 res->data.if_err_expr.var_is_ptr = old.var_is_ptr;388 res->data.if_err_expr.var_is_ptr = old.var_is_ptr;
371 res->data.if_err_expr.var_symbol = old.var_symbol;389 res->data.if_err_expr.var_symbol = old.var_symbol;
372 res->data.if_err_expr.then_node = body;390 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);
374 res->data.if_err_expr.else_node = else_body;392 res->data.if_err_expr.else_node = else_body;
375 return res;393 return res;
376 }394 }
...@@ -395,22 +413,22 @@ static AstNode *ast_parse_loop_expr_helper(...@@ -395,22 +413,22 @@ static AstNode *ast_parse_loop_expr_helper(
395 AstNode *(*for_parser)(ParseContext *),413 AstNode *(*for_parser)(ParseContext *),
396 AstNode *(*while_parser)(ParseContext *)414 AstNode *(*while_parser)(ParseContext *)
397) {415) {
398 Token *inline_token = eat_token_if(pc, TokenIdKeywordInline);416 TokenIndex inline_token = eat_token_if(pc, TokenIdKeywordInline);
399 AstNode *for_expr = for_parser(pc);417 AstNode *for_expr = for_parser(pc);
400 if (for_expr != nullptr) {418 if (for_expr != nullptr) {
401 assert(for_expr->type == NodeTypeForExpr);419 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;
403 return for_expr;421 return for_expr;
404 }422 }
405423
406 AstNode *while_expr = while_parser(pc);424 AstNode *while_expr = while_parser(pc);
407 if (while_expr != nullptr) {425 if (while_expr != nullptr) {
408 assert(while_expr->type == NodeTypeWhileExpr);426 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;
410 return while_expr;428 return while_expr;
411 }429 }
412430
413 if (inline_token != nullptr)431 if (inline_token != 0)
414 ast_invalid_token_error(pc, peek_token(pc));432 ast_invalid_token_error(pc, peek_token(pc));
415 return nullptr;433 return nullptr;
416}434}
...@@ -423,7 +441,7 @@ static AstNode *ast_parse_for_expr_helper(ParseContext *pc, AstNode *(*body_pars...@@ -423,7 +441,7 @@ static AstNode *ast_parse_for_expr_helper(ParseContext *pc, AstNode *(*body_pars
423441
424 AstNode *body = ast_expect(pc, body_parser);442 AstNode *body = ast_expect(pc, body_parser);
425 AstNode *else_body = nullptr;443 AstNode *else_body = nullptr;
426 if (eat_token_if(pc, TokenIdKeywordElse) != nullptr)444 if (eat_token_if(pc, TokenIdKeywordElse) != 0)
427 else_body = ast_expect(pc, body_parser);445 else_body = ast_expect(pc, body_parser);
428446
429 assert(res->type == NodeTypeForExpr);447 assert(res->type == NodeTypeForExpr);
...@@ -439,24 +457,24 @@ static AstNode *ast_parse_while_expr_helper(ParseContext *pc, AstNode *(*body_pa...@@ -439,24 +457,24 @@ static AstNode *ast_parse_while_expr_helper(ParseContext *pc, AstNode *(*body_pa
439 return nullptr;457 return nullptr;
440458
441 AstNode *body = ast_expect(pc, body_parser);459 AstNode *body = ast_expect(pc, body_parser);
442 Token *err_payload = nullptr;460 TokenIndex err_payload = 0;
443 AstNode *else_body = nullptr;461 AstNode *else_body = nullptr;
444 if (eat_token_if(pc, TokenIdKeywordElse) != nullptr) {462 if (eat_token_if(pc, TokenIdKeywordElse) != 0) {
445 err_payload = ast_parse_payload(pc);463 err_payload = ast_parse_payload(pc);
446 else_body = ast_expect(pc, body_parser);464 else_body = ast_expect(pc, body_parser);
447 }465 }
448466
449 assert(res->type == NodeTypeWhileExpr);467 assert(res->type == NodeTypeWhileExpr);
450 res->data.while_expr.body = body;468 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);
452 res->data.while_expr.else_node = else_body;470 res->data.while_expr.else_node = else_body;
453 return res;471 return res;
454}472}
455473
456template<TokenId id, BinOpType op>474template<TokenId id, BinOpType op>
457AstNode *ast_parse_bin_op_simple(ParseContext *pc) {475AstNode *ast_parse_bin_op_simple(ParseContext *pc) {
458 Token *op_token = eat_token_if(pc, id);476 TokenIndex op_token = eat_token_if(pc, id);
459 if (op_token == nullptr)477 if (op_token == 0)
460 return nullptr;478 return nullptr;
461479
462 AstNode *res = ast_create_node(pc, NodeTypeBinOpExpr, op_token);480 AstNode *res = ast_create_node(pc, NodeTypeBinOpExpr, op_token);
...@@ -464,20 +482,25 @@ AstNode *ast_parse_bin_op_simple(ParseContext *pc) {...@@ -464,20 +482,25 @@ AstNode *ast_parse_bin_op_simple(ParseContext *pc) {
464 return res;482 return res;
465}483}
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
468 ParseContext pc = {};488 ParseContext pc = {};
469 pc.err_color = err_color;489 pc.err_color = err_color;
470 pc.owner = owner;490 pc.owner = owner;
471 pc.buf = buf;491 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.
473 return ast_parse_root(&pc);496 return ast_parse_root(&pc);
474}497}
475498
476// Root <- skip ContainerMembers eof499// Root <- skip ContainerMembers eof
477static AstNode *ast_parse_root(ParseContext *pc) {500static AstNode *ast_parse_root(ParseContext *pc) {
478 Token *first = peek_token(pc);501 TokenIndex first = peek_token(pc);
479 AstNodeContainerDecl members = ast_parse_container_members(pc);502 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)
481 ast_invalid_token_error(pc, peek_token(pc));504 ast_invalid_token_error(pc, peek_token(pc));
482505
483 AstNode *node = ast_create_node(pc, NodeTypeContainerDecl, first);506 AstNode *node = ast_create_node(pc, NodeTypeContainerDecl, first);
...@@ -486,70 +509,26 @@ static AstNode *ast_parse_root(ParseContext *pc) {...@@ -486,70 +509,26 @@ static AstNode *ast_parse_root(ParseContext *pc) {
486 node->data.container_decl.layout = ContainerLayoutAuto;509 node->data.container_decl.layout = ContainerLayoutAuto;
487 node->data.container_decl.kind = ContainerKindStruct;510 node->data.container_decl.kind = ContainerKindStruct;
488 node->data.container_decl.is_root = true;511 node->data.container_decl.is_root = true;
489 if (buf_len(&members.doc_comments) != 0) {512 node->data.container_decl.doc_comments = members.doc_comments;
490 node->data.container_decl.doc_comments = members.doc_comments;
491 }
492513
493 return node;514 return node;
494}515}
495516
496static Token *ast_parse_multiline_string_literal(ParseContext *pc, Buf *buf) {517static TokenIndex ast_parse_multi_tok(ParseContext *pc, TokenId token_id) {
497 Token *first_str_token = nullptr;518 TokenIndex first_token = eat_token_if(pc, token_id);
498 Token *str_token = nullptr;519 TokenIndex token = first_token;
499 while ((str_token = eat_token_if(pc, TokenIdMultilineStringLiteral))) {520 while (token != 0) {
500 if (first_str_token == nullptr) {521 token = eat_token_if(pc, token_id);
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 }
519 }522 }
520 return first_str_token;523 return first_token;
521}524}
522525
523static Token *ast_parse_doc_comments(ParseContext *pc, Buf *buf) {526static TokenIndex ast_parse_doc_comments(ParseContext *pc) {
524 Token *first_doc_token = nullptr;527 return ast_parse_multi_tok(pc, TokenIdDocComment);
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;
538}528}
539529
540static void ast_parse_container_doc_comments(ParseContext *pc, Buf *buf) {530static TokenIndex ast_parse_container_doc_comments(ParseContext *pc) {
541 if (buf_len(buf) != 0 && peek_token(pc)->id == TokenIdContainerDocComment) {531 return ast_parse_multi_tok(pc, 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 }
553}532}
554533
555enum ContainerFieldState {534enum ContainerFieldState {
...@@ -570,14 +549,11 @@ enum ContainerFieldState {...@@ -570,14 +549,11 @@ enum ContainerFieldState {
570// /549// /
571static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {550static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {
572 AstNodeContainerDecl res = {};551 AstNodeContainerDecl res = {};
573 Buf tld_doc_comment_buf = BUF_INIT;
574 buf_resize(&tld_doc_comment_buf, 0);
575 ContainerFieldState field_state = ContainerFieldStateNone;552 ContainerFieldState field_state = ContainerFieldStateNone;
576 Token *first_token = nullptr;553 TokenIndex first_token = 0;
554 res.doc_comments = ast_parse_container_doc_comments(pc);
577 for (;;) {555 for (;;) {
578 ast_parse_container_doc_comments(pc, &tld_doc_comment_buf);556 TokenIndex peeked_token = peek_token(pc);
579
580 Token *peeked_token = peek_token(pc);
581557
582 AstNode *test_decl = ast_parse_test_decl(pc);558 AstNode *test_decl = ast_parse_test_decl(pc);
583 if (test_decl != nullptr) {559 if (test_decl != nullptr) {
...@@ -599,15 +575,14 @@ static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {...@@ -599,15 +575,14 @@ static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {
599 continue;575 continue;
600 }576 }
601577
602 Buf doc_comment_buf = BUF_INIT;578 TokenIndex first_doc_token = ast_parse_doc_comments(pc);
603 ast_parse_doc_comments(pc, &doc_comment_buf);
604579
605 peeked_token = peek_token(pc);580 peeked_token = peek_token(pc);
606581
607 Token *visib_token = eat_token_if(pc, TokenIdKeywordPub);582 TokenIndex visib_token = eat_token_if(pc, TokenIdKeywordPub);
608 VisibMod visib_mod = visib_token != nullptr ? VisibModPub : VisibModPrivate;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);
611 if (top_level_decl != nullptr) {586 if (top_level_decl != nullptr) {
612 if (field_state == ContainerFieldStateSeen) {587 if (field_state == ContainerFieldStateSeen) {
613 field_state = ContainerFieldStateEnd;588 field_state = ContainerFieldStateEnd;
...@@ -617,11 +592,11 @@ static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {...@@ -617,11 +592,11 @@ static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {
617 continue;592 continue;
618 }593 }
619594
620 if (visib_token != nullptr) {595 if (visib_token != 0) {
621 ast_error(pc, peek_token(pc), "expected function or variable declaration after pub");596 ast_error(pc, peek_token(pc), "expected function or variable declaration after pub");
622 }597 }
623598
624 Token *comptime_token = eat_token_if(pc, TokenIdKeywordCompTime);599 TokenIndex comptime_token = eat_token_if(pc, TokenIdKeywordCompTime);
625600
626 AstNode *container_field = ast_parse_container_field(pc);601 AstNode *container_field = ast_parse_container_field(pc);
627 if (container_field != nullptr) {602 if (container_field != nullptr) {
...@@ -636,10 +611,10 @@ static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {...@@ -636,10 +611,10 @@ static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {
636 }611 }
637612
638 assert(container_field->type == NodeTypeStructField);613 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;
640 container_field->data.struct_field.comptime_token = comptime_token;615 container_field->data.struct_field.comptime_token = comptime_token;
641 res.fields.append(container_field);616 res.fields.append(container_field);
642 if (eat_token_if(pc, TokenIdComma) != nullptr) {617 if (eat_token_if(pc, TokenIdComma) != 0) {
643 continue;618 continue;
644 } else {619 } else {
645 break;620 break;
...@@ -648,33 +623,32 @@ static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {...@@ -648,33 +623,32 @@ static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {
648623
649 break;624 break;
650 }625 }
651 res.doc_comments = tld_doc_comment_buf;
652 return res;626 return res;
653}627}
654628
655// TestDecl <- KEYWORD_test STRINGLITERALSINGLE Block629// TestDecl <- KEYWORD_test STRINGLITERALSINGLE Block
656static AstNode *ast_parse_test_decl(ParseContext *pc) {630static AstNode *ast_parse_test_decl(ParseContext *pc) {
657 Token *test = eat_token_if(pc, TokenIdKeywordTest);631 TokenIndex test = eat_token_if(pc, TokenIdKeywordTest);
658 if (test == nullptr)632 if (test == 0)
659 return nullptr;633 return nullptr;
660634
661 Token *name = eat_token_if(pc, TokenIdStringLiteral);635 TokenIndex name = eat_token_if(pc, TokenIdStringLiteral);
662 AstNode *block = ast_expect(pc, ast_parse_block);636 AstNode *block = ast_expect(pc, ast_parse_block);
663 AstNode *res = ast_create_node(pc, NodeTypeTestDecl, test);637 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;
665 res->data.test_decl.body = block;639 res->data.test_decl.body = block;
666 return res;640 return res;
667}641}
668642
669// TopLevelComptime <- KEYWORD_comptime BlockExpr643// TopLevelComptime <- KEYWORD_comptime BlockExpr
670static AstNode *ast_parse_top_level_comptime(ParseContext *pc) {644static AstNode *ast_parse_top_level_comptime(ParseContext *pc) {
671 Token *comptime = eat_token_if(pc, TokenIdKeywordCompTime);645 TokenIndex comptime = eat_token_if(pc, TokenIdKeywordCompTime);
672 if (comptime == nullptr)646 if (comptime == 0)
673 return nullptr;647 return nullptr;
674648
675 // 1 token lookahead because it could be a comptime struct field649 // 1 token lookahead because it could be a comptime struct field
676 Token *lbrace = peek_token(pc);650 TokenIndex lbrace = peek_token(pc);
677 if (lbrace->id != TokenIdLBrace) {651 if (pc->token_ids[lbrace] != TokenIdLBrace) {
678 put_back_token(pc);652 put_back_token(pc);
679 return nullptr;653 return nullptr;
680 }654 }
...@@ -689,39 +663,40 @@ static AstNode *ast_parse_top_level_comptime(ParseContext *pc) {...@@ -689,39 +663,40 @@ static AstNode *ast_parse_top_level_comptime(ParseContext *pc) {
689// <- (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE? / (KEYWORD_inline / KEYWORD_noinline))? FnProto (SEMICOLON / Block)663// <- (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE? / (KEYWORD_inline / KEYWORD_noinline))? FnProto (SEMICOLON / Block)
690// / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl664// / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl
691// / KEYWORD_use Expr SEMICOLON665// / KEYWORD_use Expr SEMICOLON
692static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, Buf *doc_comments) {666static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod,
693 Token *first = eat_token_if(pc, TokenIdKeywordExport);667 TokenIndex doc_comments)
694 if (first == nullptr)668{
669 TokenIndex first = eat_token_if(pc, TokenIdKeywordExport);
670 if (first == 0)
695 first = eat_token_if(pc, TokenIdKeywordExtern);671 first = eat_token_if(pc, TokenIdKeywordExtern);
696 if (first == nullptr)672 if (first == 0)
697 first = eat_token_if(pc, TokenIdKeywordInline);673 first = eat_token_if(pc, TokenIdKeywordInline);
698 if (first == nullptr)674 if (first == 0)
699 first = eat_token_if(pc, TokenIdKeywordNoInline);675 first = eat_token_if(pc, TokenIdKeywordNoInline);
700 if (first != nullptr) {676 if (first != 0) {
701 Token *lib_name = nullptr;677 TokenIndex lib_name = 0;
702 if (first->id == TokenIdKeywordExtern)678 if (pc->token_ids[first] == TokenIdKeywordExtern)
703 lib_name = eat_token_if(pc, TokenIdStringLiteral);679 lib_name = eat_token_if(pc, TokenIdStringLiteral);
704680
705 if (first->id != TokenIdKeywordNoInline && first->id != TokenIdKeywordInline) {681 if (pc->token_ids[first] != TokenIdKeywordNoInline && pc->token_ids[first] != TokenIdKeywordInline) {
706 Token *thread_local_kw = eat_token_if(pc, TokenIdKeywordThreadLocal);682 TokenIndex thread_local_kw = eat_token_if(pc, TokenIdKeywordThreadLocal);
707 AstNode *var_decl = ast_parse_var_decl(pc);683 AstNode *var_decl = ast_parse_var_decl(pc);
708 if (var_decl != nullptr) {684 if (var_decl != nullptr) {
709 assert(var_decl->type == NodeTypeVariableDeclaration);685 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) {
711 ast_error(pc, first, "extern variables have no initializers");687 ast_error(pc, first, "extern variables have no initializers");
712 }688 }
713 var_decl->line = first->start_line;689 var_decl->main_token = first;
714 var_decl->column = first->start_column;
715 var_decl->data.variable_declaration.threadlocal_tok = thread_local_kw;690 var_decl->data.variable_declaration.threadlocal_tok = thread_local_kw;
716 var_decl->data.variable_declaration.visib_mod = visib_mod;691 var_decl->data.variable_declaration.visib_mod = visib_mod;
717 var_decl->data.variable_declaration.doc_comments = *doc_comments;692 var_decl->data.variable_declaration.doc_comments = doc_comments;
718 var_decl->data.variable_declaration.is_extern = first->id == TokenIdKeywordExtern;693 var_decl->data.variable_declaration.is_extern = pc->token_ids[first] == TokenIdKeywordExtern;
719 var_decl->data.variable_declaration.is_export = first->id == TokenIdKeywordExport;694 var_decl->data.variable_declaration.is_export = pc->token_ids[first] == TokenIdKeywordExport;
720 var_decl->data.variable_declaration.lib_name = token_buf(lib_name);695 var_decl->data.variable_declaration.lib_name = token_buf(pc, lib_name);
721 return var_decl;696 return var_decl;
722 }697 }
723698
724 if (thread_local_kw != nullptr)699 if (thread_local_kw != 0)
725 put_back_token(pc);700 put_back_token(pc);
726 }701 }
727702
...@@ -732,14 +707,13 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B...@@ -732,14 +707,13 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
732 expect_token(pc, TokenIdSemicolon);707 expect_token(pc, TokenIdSemicolon);
733708
734 assert(fn_proto->type == NodeTypeFnProto);709 assert(fn_proto->type == NodeTypeFnProto);
735 fn_proto->line = first->start_line;710 fn_proto->main_token = first;
736 fn_proto->column = first->start_column;
737 fn_proto->data.fn_proto.visib_mod = visib_mod;711 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;
739 if (!fn_proto->data.fn_proto.is_extern)713 if (!fn_proto->data.fn_proto.is_extern)
740 fn_proto->data.fn_proto.is_extern = first->id == TokenIdKeywordExtern;714 fn_proto->data.fn_proto.is_extern = pc->token_ids[first] == TokenIdKeywordExtern;
741 fn_proto->data.fn_proto.is_export = first->id == TokenIdKeywordExport;715 fn_proto->data.fn_proto.is_export = pc->token_ids[first] == TokenIdKeywordExport;
742 switch (first->id) {716 switch (pc->token_ids[first]) {
743 case TokenIdKeywordInline:717 case TokenIdKeywordInline:
744 fn_proto->data.fn_proto.fn_inline = FnInlineAlways;718 fn_proto->data.fn_proto.fn_inline = FnInlineAlways;
745 break;719 break;
...@@ -750,7 +724,7 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B...@@ -750,7 +724,7 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
750 fn_proto->data.fn_proto.fn_inline = FnInlineAuto;724 fn_proto->data.fn_proto.fn_inline = FnInlineAuto;
751 break;725 break;
752 }726 }
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
755 AstNode *res = fn_proto;729 AstNode *res = fn_proto;
756 if (body != nullptr) {730 if (body != nullptr) {
...@@ -769,17 +743,17 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B...@@ -769,17 +743,17 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
769 ast_invalid_token_error(pc, peek_token(pc));743 ast_invalid_token_error(pc, peek_token(pc));
770 }744 }
771745
772 Token *thread_local_kw = eat_token_if(pc, TokenIdKeywordThreadLocal);746 TokenIndex thread_local_kw = eat_token_if(pc, TokenIdKeywordThreadLocal);
773 AstNode *var_decl = ast_parse_var_decl(pc);747 AstNode *var_decl = ast_parse_var_decl(pc);
774 if (var_decl != nullptr) {748 if (var_decl != nullptr) {
775 assert(var_decl->type == NodeTypeVariableDeclaration);749 assert(var_decl->type == NodeTypeVariableDeclaration);
776 var_decl->data.variable_declaration.visib_mod = visib_mod;750 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;
778 var_decl->data.variable_declaration.threadlocal_tok = thread_local_kw;752 var_decl->data.variable_declaration.threadlocal_tok = thread_local_kw;
779 return var_decl;753 return var_decl;
780 }754 }
781755
782 if (thread_local_kw != nullptr)756 if (thread_local_kw != 0)
783 put_back_token(pc);757 put_back_token(pc);
784758
785 AstNode *fn_proto = ast_parse_fn_proto(pc);759 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...@@ -790,7 +764,7 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
790764
791 assert(fn_proto->type == NodeTypeFnProto);765 assert(fn_proto->type == NodeTypeFnProto);
792 fn_proto->data.fn_proto.visib_mod = visib_mod;766 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;
794 AstNode *res = fn_proto;768 AstNode *res = fn_proto;
795 if (body != nullptr) {769 if (body != nullptr) {
796 res = ast_create_node_copy_line_info(pc, NodeTypeFnDef, fn_proto);770 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...@@ -802,8 +776,8 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
802 return res;776 return res;
803 }777 }
804778
805 Token *usingnamespace = eat_token_if(pc, TokenIdKeywordUsingNamespace);779 TokenIndex usingnamespace = eat_token_if(pc, TokenIdKeywordUsingNamespace);
806 if (usingnamespace != nullptr) {780 if (usingnamespace != 0) {
807 AstNode *expr = ast_expect(pc, ast_parse_expr);781 AstNode *expr = ast_expect(pc, ast_parse_expr);
808 expect_token(pc, TokenIdSemicolon);782 expect_token(pc, TokenIdSemicolon);
809783
...@@ -818,12 +792,12 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B...@@ -818,12 +792,12 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
818792
819// FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_anytype / TypeExpr)793// FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_anytype / TypeExpr)
820static AstNode *ast_parse_fn_proto(ParseContext *pc) {794static AstNode *ast_parse_fn_proto(ParseContext *pc) {
821 Token *first = eat_token_if(pc, TokenIdKeywordFn);795 TokenIndex first = eat_token_if(pc, TokenIdKeywordFn);
822 if (first == nullptr) {796 if (first == 0) {
823 return nullptr;797 return nullptr;
824 }798 }
825799
826 Token *identifier = eat_token_if(pc, TokenIdSymbol);800 TokenIndex identifier = eat_token_if(pc, TokenIdIdentifier);
827 expect_token(pc, TokenIdLParen);801 expect_token(pc, TokenIdLParen);
828 ZigList<AstNode *> params = ast_parse_list(pc, TokenIdComma, ast_parse_param_decl);802 ZigList<AstNode *> params = ast_parse_list(pc, TokenIdComma, ast_parse_param_decl);
829 expect_token(pc, TokenIdRParen);803 expect_token(pc, TokenIdRParen);
...@@ -831,29 +805,29 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {...@@ -831,29 +805,29 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
831 AstNode *align_expr = ast_parse_byte_align(pc);805 AstNode *align_expr = ast_parse_byte_align(pc);
832 AstNode *section_expr = ast_parse_link_section(pc);806 AstNode *section_expr = ast_parse_link_section(pc);
833 AstNode *callconv_expr = ast_parse_callconv(pc);807 AstNode *callconv_expr = ast_parse_callconv(pc);
834 Token *exmark = nullptr;808 TokenIndex exmark = 0;
835 AstNode *return_type = nullptr;809 AstNode *return_type = nullptr;
836810
837 exmark = eat_token_if(pc, TokenIdBang);811 exmark = eat_token_if(pc, TokenIdBang);
838 return_type = ast_parse_type_expr(pc);812 return_type = ast_parse_type_expr(pc);
839 if (return_type == nullptr) {813 if (return_type == nullptr) {
840 Token *next = peek_token(pc);814 TokenIndex next = peek_token(pc);
841 ast_error(815 ast_error(
842 pc,816 pc,
843 next,817 next,
844 "expected return type (use 'void' to return nothing), found: '%s'",818 "expected return type (use 'void' to return nothing), found: '%s'",
845 token_name(next->id)819 token_name(pc->token_ids[next])
846 );820 );
847 }821 }
848822
849 AstNode *res = ast_create_node(pc, NodeTypeFnProto, first);823 AstNode *res = ast_create_node(pc, NodeTypeFnProto, first);
850 res->data.fn_proto = {};824 res->data.fn_proto = {};
851 res->data.fn_proto.name = token_buf(identifier);825 res->data.fn_proto.name = token_buf(pc, identifier);
852 res->data.fn_proto.params = params;826 res->data.fn_proto.params = params;
853 res->data.fn_proto.align_expr = align_expr;827 res->data.fn_proto.align_expr = align_expr;
854 res->data.fn_proto.section_expr = section_expr;828 res->data.fn_proto.section_expr = section_expr;
855 res->data.fn_proto.callconv_expr = callconv_expr;829 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;
857 res->data.fn_proto.return_type = return_type;831 res->data.fn_proto.return_type = return_type;
858832
859 for (size_t i = 0; i < params.length; i++) {833 for (size_t i = 0; i < params.length; i++) {
...@@ -869,28 +843,28 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {...@@ -869,28 +843,28 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
869843
870// VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON844// VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
871static AstNode *ast_parse_var_decl(ParseContext *pc) {845static AstNode *ast_parse_var_decl(ParseContext *pc) {
872 Token *mut_kw = eat_token_if(pc, TokenIdKeywordConst);846 TokenIndex mut_kw = eat_token_if(pc, TokenIdKeywordConst);
873 if (mut_kw == nullptr)847 if (mut_kw == 0)
874 mut_kw = eat_token_if(pc, TokenIdKeywordVar);848 mut_kw = eat_token_if(pc, TokenIdKeywordVar);
875 if (mut_kw == nullptr)849 if (mut_kw == 0)
876 return nullptr;850 return nullptr;
877851
878 Token *identifier = expect_token(pc, TokenIdSymbol);852 TokenIndex identifier = expect_token(pc, TokenIdIdentifier);
879 AstNode *type_expr = nullptr;853 AstNode *type_expr = nullptr;
880 if (eat_token_if(pc, TokenIdColon) != nullptr)854 if (eat_token_if(pc, TokenIdColon) != 0)
881 type_expr = ast_expect(pc, ast_parse_type_expr);855 type_expr = ast_expect(pc, ast_parse_type_expr);
882856
883 AstNode *align_expr = ast_parse_byte_align(pc);857 AstNode *align_expr = ast_parse_byte_align(pc);
884 AstNode *section_expr = ast_parse_link_section(pc);858 AstNode *section_expr = ast_parse_link_section(pc);
885 AstNode *expr = nullptr;859 AstNode *expr = nullptr;
886 if (eat_token_if(pc, TokenIdEq) != nullptr)860 if (eat_token_if(pc, TokenIdEq) != 0)
887 expr = ast_expect(pc, ast_parse_expr);861 expr = ast_expect(pc, ast_parse_expr);
888862
889 expect_token(pc, TokenIdSemicolon);863 expect_token(pc, TokenIdSemicolon);
890864
891 AstNode *res = ast_create_node(pc, NodeTypeVariableDeclaration, mut_kw);865 AstNode *res = ast_create_node(pc, NodeTypeVariableDeclaration, mut_kw);
892 res->data.variable_declaration.is_const = mut_kw->id == TokenIdKeywordConst;866 res->data.variable_declaration.is_const = pc->token_ids[mut_kw] == TokenIdKeywordConst;
893 res->data.variable_declaration.symbol = token_buf(identifier);867 res->data.variable_declaration.symbol = token_buf(pc, identifier);
894 res->data.variable_declaration.type = type_expr;868 res->data.variable_declaration.type = type_expr;
895 res->data.variable_declaration.align_expr = align_expr;869 res->data.variable_declaration.align_expr = align_expr;
896 res->data.variable_declaration.section_expr = section_expr;870 res->data.variable_declaration.section_expr = section_expr;
...@@ -900,14 +874,14 @@ static AstNode *ast_parse_var_decl(ParseContext *pc) {...@@ -900,14 +874,14 @@ static AstNode *ast_parse_var_decl(ParseContext *pc) {
900874
901// ContainerField <- KEYWORD_comptime? IDENTIFIER (COLON TypeExpr ByteAlign?)? (EQUAL Expr)?875// ContainerField <- KEYWORD_comptime? IDENTIFIER (COLON TypeExpr ByteAlign?)? (EQUAL Expr)?
902static AstNode *ast_parse_container_field(ParseContext *pc) {876static AstNode *ast_parse_container_field(ParseContext *pc) {
903 Token *identifier = eat_token_if(pc, TokenIdSymbol);877 TokenIndex identifier = eat_token_if(pc, TokenIdIdentifier);
904 if (identifier == nullptr)878 if (identifier == 0)
905 return nullptr;879 return nullptr;
906880
907 AstNode *type_expr = nullptr;881 AstNode *type_expr = nullptr;
908 if (eat_token_if(pc, TokenIdColon) != nullptr) {882 if (eat_token_if(pc, TokenIdColon) != 0) {
909 Token *anytype_tok = eat_token_if(pc, TokenIdKeywordAnyType);883 TokenIndex anytype_tok = eat_token_if(pc, TokenIdKeywordAnyType);
910 if (anytype_tok != nullptr) {884 if (anytype_tok != 0) {
911 type_expr = ast_create_node(pc, NodeTypeAnyTypeField, anytype_tok);885 type_expr = ast_create_node(pc, NodeTypeAnyTypeField, anytype_tok);
912 } else {886 } else {
913 type_expr = ast_expect(pc, ast_parse_type_expr);887 type_expr = ast_expect(pc, ast_parse_type_expr);
...@@ -915,11 +889,11 @@ static AstNode *ast_parse_container_field(ParseContext *pc) {...@@ -915,11 +889,11 @@ static AstNode *ast_parse_container_field(ParseContext *pc) {
915 }889 }
916 AstNode *align_expr = ast_parse_byte_align(pc);890 AstNode *align_expr = ast_parse_byte_align(pc);
917 AstNode *expr = nullptr;891 AstNode *expr = nullptr;
918 if (eat_token_if(pc, TokenIdEq) != nullptr)892 if (eat_token_if(pc, TokenIdEq) != 0)
919 expr = ast_expect(pc, ast_parse_expr);893 expr = ast_expect(pc, ast_parse_expr);
920894
921 AstNode *res = ast_create_node(pc, NodeTypeStructField, identifier);895 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);
923 res->data.struct_field.type = type_expr;897 res->data.struct_field.type = type_expr;
924 res->data.struct_field.value = expr;898 res->data.struct_field.value = expr;
925 res->data.struct_field.align_expr = align_expr;899 res->data.struct_field.align_expr = align_expr;
...@@ -938,52 +912,52 @@ static AstNode *ast_parse_container_field(ParseContext *pc) {...@@ -938,52 +912,52 @@ static AstNode *ast_parse_container_field(ParseContext *pc) {
938// / SwitchExpr912// / SwitchExpr
939// / AssignExpr SEMICOLON913// / AssignExpr SEMICOLON
940static AstNode *ast_parse_statement(ParseContext *pc) {914static AstNode *ast_parse_statement(ParseContext *pc) {
941 Token *comptime = eat_token_if(pc, TokenIdKeywordCompTime);915 TokenIndex comptime = eat_token_if(pc, TokenIdKeywordCompTime);
942 AstNode *var_decl = ast_parse_var_decl(pc);916 AstNode *var_decl = ast_parse_var_decl(pc);
943 if (var_decl != nullptr) {917 if (var_decl != nullptr) {
944 assert(var_decl->type == NodeTypeVariableDeclaration);918 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;
946 return var_decl;920 return var_decl;
947 }921 }
948922
949 if (comptime != nullptr) {923 if (comptime != 0) {
950 AstNode *statement = ast_expect(pc, ast_parse_block_expr_statement);924 AstNode *statement = ast_expect(pc, ast_parse_block_expr_statement);
951 AstNode *res = ast_create_node(pc, NodeTypeCompTime, comptime);925 AstNode *res = ast_create_node(pc, NodeTypeCompTime, comptime);
952 res->data.comptime_expr.expr = statement;926 res->data.comptime_expr.expr = statement;
953 return res;927 return res;
954 }928 }
955929
956 Token *nosuspend = eat_token_if(pc, TokenIdKeywordNoSuspend);930 TokenIndex nosuspend = eat_token_if(pc, TokenIdKeywordNoSuspend);
957 if (nosuspend != nullptr) {931 if (nosuspend != 0) {
958 AstNode *statement = ast_expect(pc, ast_parse_block_expr_statement);932 AstNode *statement = ast_expect(pc, ast_parse_block_expr_statement);
959 AstNode *res = ast_create_node(pc, NodeTypeNoSuspend, nosuspend);933 AstNode *res = ast_create_node(pc, NodeTypeNoSuspend, nosuspend);
960 res->data.nosuspend_expr.expr = statement;934 res->data.nosuspend_expr.expr = statement;
961 return res;935 return res;
962 }936 }
963937
964 Token *suspend = eat_token_if(pc, TokenIdKeywordSuspend);938 TokenIndex suspend = eat_token_if(pc, TokenIdKeywordSuspend);
965 if (suspend != nullptr) {939 if (suspend != 0) {
966 AstNode *statement = ast_expect(pc, ast_parse_block_expr_statement);940 AstNode *statement = ast_expect(pc, ast_parse_block_expr_statement);
967 AstNode *res = ast_create_node(pc, NodeTypeSuspend, suspend);941 AstNode *res = ast_create_node(pc, NodeTypeSuspend, suspend);
968 res->data.suspend.block = statement;942 res->data.suspend.block = statement;
969 return res;943 return res;
970 }944 }
971945
972 Token *defer = eat_token_if(pc, TokenIdKeywordDefer);946 TokenIndex defer = eat_token_if(pc, TokenIdKeywordDefer);
973 if (defer == nullptr)947 if (defer == 0)
974 defer = eat_token_if(pc, TokenIdKeywordErrdefer);948 defer = eat_token_if(pc, TokenIdKeywordErrdefer);
975 if (defer != nullptr) {949 if (defer != 0) {
976 Token *payload = (defer->id == TokenIdKeywordErrdefer) ?950 TokenIndex payload = (pc->token_ids[defer] == TokenIdKeywordErrdefer) ?
977 ast_parse_payload(pc) : nullptr;951 ast_parse_payload(pc) : 0;
978 AstNode *statement = ast_expect(pc, ast_parse_block_expr_statement);952 AstNode *statement = ast_expect(pc, ast_parse_block_expr_statement);
979 AstNode *res = ast_create_node(pc, NodeTypeDefer, defer);953 AstNode *res = ast_create_node(pc, NodeTypeDefer, defer);
980954
981 res->data.defer.kind = ReturnKindUnconditional;955 res->data.defer.kind = ReturnKindUnconditional;
982 res->data.defer.expr = statement;956 res->data.defer.expr = statement;
983 if (defer->id == TokenIdKeywordErrdefer) {957 if (pc->token_ids[defer] == TokenIdKeywordErrdefer) {
984 res->data.defer.kind = ReturnKindError;958 res->data.defer.kind = ReturnKindError;
985 if (payload != nullptr)959 if (payload != 0)
986 res->data.defer.err_payload = token_symbol(pc, payload);960 res->data.defer.err_payload = token_identifier(pc, payload);
987 }961 }
988 return res;962 return res;
989 }963 }
...@@ -1025,13 +999,13 @@ static AstNode *ast_parse_if_statement(ParseContext *pc) {...@@ -1025,13 +999,13 @@ static AstNode *ast_parse_if_statement(ParseContext *pc) {
1025 }999 }
10261000
1027 if (body == nullptr) {1001 if (body == nullptr) {
1028 Token *tok = eat_token(pc);1002 TokenIndex tok = eat_token(pc);
1029 ast_error(pc, tok, "expected if body, found '%s'", token_name(tok->id));1003 ast_error(pc, tok, "expected if body, found '%s'", token_name(pc->token_ids[tok]));
1030 }1004 }
10311005
1032 Token *err_payload = nullptr;1006 TokenIndex err_payload = 0;
1033 AstNode *else_body = nullptr;1007 AstNode *else_body = nullptr;
1034 if (eat_token_if(pc, TokenIdKeywordElse) != nullptr) {1008 if (eat_token_if(pc, TokenIdKeywordElse) != 0) {
1035 err_payload = ast_parse_payload(pc);1009 err_payload = ast_parse_payload(pc);
1036 else_body = ast_expect(pc, ast_parse_statement);1010 else_body = ast_expect(pc, ast_parse_statement);
1037 }1011 }
...@@ -1040,14 +1014,14 @@ static AstNode *ast_parse_if_statement(ParseContext *pc) {...@@ -1040,14 +1014,14 @@ static AstNode *ast_parse_if_statement(ParseContext *pc) {
1040 expect_token(pc, TokenIdSemicolon);1014 expect_token(pc, TokenIdSemicolon);
10411015
1042 assert(res->type == NodeTypeIfOptional);1016 assert(res->type == NodeTypeIfOptional);
1043 if (err_payload != nullptr) {1017 if (err_payload != 0) {
1044 AstNodeTestExpr old = res->data.test_expr;1018 AstNodeTestExpr old = res->data.test_expr;
1045 res->type = NodeTypeIfErrorExpr;1019 res->type = NodeTypeIfErrorExpr;
1046 res->data.if_err_expr.target_node = old.target_node;1020 res->data.if_err_expr.target_node = old.target_node;
1047 res->data.if_err_expr.var_is_ptr = old.var_is_ptr;1021 res->data.if_err_expr.var_is_ptr = old.var_is_ptr;
1048 res->data.if_err_expr.var_symbol = old.var_symbol;1022 res->data.if_err_expr.var_symbol = old.var_symbol;
1049 res->data.if_err_expr.then_node = body;1023 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);
1051 res->data.if_err_expr.else_node = else_body;1025 res->data.if_err_expr.else_node = else_body;
1052 return res;1026 return res;
1053 }1027 }
...@@ -1068,11 +1042,11 @@ static AstNode *ast_parse_if_statement(ParseContext *pc) {...@@ -1068,11 +1042,11 @@ static AstNode *ast_parse_if_statement(ParseContext *pc) {
10681042
1069// LabeledStatement <- BlockLabel? (Block / LoopStatement)1043// LabeledStatement <- BlockLabel? (Block / LoopStatement)
1070static AstNode *ast_parse_labeled_statement(ParseContext *pc) {1044static AstNode *ast_parse_labeled_statement(ParseContext *pc) {
1071 Token *label = ast_parse_block_label(pc);1045 TokenIndex label = ast_parse_block_label(pc);
1072 AstNode *block = ast_parse_block(pc);1046 AstNode *block = ast_parse_block(pc);
1073 if (block != nullptr) {1047 if (block != nullptr) {
1074 assert(block->type == NodeTypeBlock);1048 assert(block->type == NodeTypeBlock);
1075 block->data.block.name = token_buf(label);1049 block->data.block.name = token_buf(pc, label);
1076 return block;1050 return block;
1077 }1051 }
10781052
...@@ -1080,10 +1054,10 @@ static AstNode *ast_parse_labeled_statement(ParseContext *pc) {...@@ -1080,10 +1054,10 @@ static AstNode *ast_parse_labeled_statement(ParseContext *pc) {
1080 if (loop != nullptr) {1054 if (loop != nullptr) {
1081 switch (loop->type) {1055 switch (loop->type) {
1082 case NodeTypeForExpr:1056 case NodeTypeForExpr:
1083 loop->data.for_expr.name = token_buf(label);1057 loop->data.for_expr.name = token_buf(pc, label);
1084 break;1058 break;
1085 case NodeTypeWhileExpr:1059 case NodeTypeWhileExpr:
1086 loop->data.while_expr.name = token_buf(label);1060 loop->data.while_expr.name = token_buf(pc, label);
1087 break;1061 break;
1088 default:1062 default:
1089 zig_unreachable();1063 zig_unreachable();
...@@ -1091,29 +1065,29 @@ static AstNode *ast_parse_labeled_statement(ParseContext *pc) {...@@ -1091,29 +1065,29 @@ static AstNode *ast_parse_labeled_statement(ParseContext *pc) {
1091 return loop;1065 return loop;
1092 }1066 }
10931067
1094 if (label != nullptr)1068 if (label != 0)
1095 ast_invalid_token_error(pc, peek_token(pc));1069 ast_invalid_token_error(pc, peek_token(pc));
1096 return nullptr;1070 return nullptr;
1097}1071}
10981072
1099// LoopStatement <- KEYWORD_inline? (ForStatement / WhileStatement)1073// LoopStatement <- KEYWORD_inline? (ForStatement / WhileStatement)
1100static AstNode *ast_parse_loop_statement(ParseContext *pc) {1074static 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);
1102 AstNode *for_statement = ast_parse_for_statement(pc);1076 AstNode *for_statement = ast_parse_for_statement(pc);
1103 if (for_statement != nullptr) {1077 if (for_statement != nullptr) {
1104 assert(for_statement->type == NodeTypeForExpr);1078 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;
1106 return for_statement;1080 return for_statement;
1107 }1081 }
11081082
1109 AstNode *while_statement = ast_parse_while_statement(pc);1083 AstNode *while_statement = ast_parse_while_statement(pc);
1110 if (while_statement != nullptr) {1084 if (while_statement != nullptr) {
1111 assert(while_statement->type == NodeTypeWhileExpr);1085 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;
1113 return while_statement;1087 return while_statement;
1114 }1088 }
11151089
1116 if (inline_token != nullptr)1090 if (inline_token != 0)
1117 ast_invalid_token_error(pc, peek_token(pc));1091 ast_invalid_token_error(pc, peek_token(pc));
1118 return nullptr;1092 return nullptr;
1119}1093}
...@@ -1134,12 +1108,12 @@ static AstNode *ast_parse_for_statement(ParseContext *pc) {...@@ -1134,12 +1108,12 @@ static AstNode *ast_parse_for_statement(ParseContext *pc) {
1134 }1108 }
11351109
1136 if (body == nullptr) {1110 if (body == nullptr) {
1137 Token *tok = eat_token(pc);1111 TokenIndex tok = eat_token(pc);
1138 ast_error(pc, tok, "expected loop body, found '%s'", token_name(tok->id));1112 ast_error(pc, tok, "expected loop body, found '%s'", token_name(pc->token_ids[tok]));
1139 }1113 }
11401114
1141 AstNode *else_body = nullptr;1115 AstNode *else_body = nullptr;
1142 if (eat_token_if(pc, TokenIdKeywordElse) != nullptr) {1116 if (eat_token_if(pc, TokenIdKeywordElse) != 0) {
1143 else_body = ast_expect(pc, ast_parse_statement);1117 else_body = ast_expect(pc, ast_parse_statement);
1144 }1118 }
11451119
...@@ -1168,13 +1142,13 @@ static AstNode *ast_parse_while_statement(ParseContext *pc) {...@@ -1168,13 +1142,13 @@ static AstNode *ast_parse_while_statement(ParseContext *pc) {
1168 }1142 }
11691143
1170 if (body == nullptr) {1144 if (body == nullptr) {
1171 Token *tok = eat_token(pc);1145 TokenIndex tok = eat_token(pc);
1172 ast_error(pc, tok, "expected loop body, found '%s'", token_name(tok->id));1146 ast_error(pc, tok, "expected loop body, found '%s'", token_name(pc->token_ids[tok]));
1173 }1147 }
11741148
1175 Token *err_payload = nullptr;1149 TokenIndex err_payload = 0;
1176 AstNode *else_body = nullptr;1150 AstNode *else_body = nullptr;
1177 if (eat_token_if(pc, TokenIdKeywordElse) != nullptr) {1151 if (eat_token_if(pc, TokenIdKeywordElse) != 0) {
1178 err_payload = ast_parse_payload(pc);1152 err_payload = ast_parse_payload(pc);
1179 else_body = ast_expect(pc, ast_parse_statement);1153 else_body = ast_expect(pc, ast_parse_statement);
1180 }1154 }
...@@ -1184,7 +1158,7 @@ static AstNode *ast_parse_while_statement(ParseContext *pc) {...@@ -1184,7 +1158,7 @@ static AstNode *ast_parse_while_statement(ParseContext *pc) {
11841158
1185 assert(res->type == NodeTypeWhileExpr);1159 assert(res->type == NodeTypeWhileExpr);
1186 res->data.while_expr.body = body;1160 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);
1188 res->data.while_expr.else_node = else_body;1162 res->data.while_expr.else_node = else_body;
1189 return res;1163 return res;
1190}1164}
...@@ -1209,11 +1183,11 @@ static AstNode *ast_parse_block_expr_statement(ParseContext *pc) {...@@ -1209,11 +1183,11 @@ static AstNode *ast_parse_block_expr_statement(ParseContext *pc) {
12091183
1210// BlockExpr <- BlockLabel? Block1184// BlockExpr <- BlockLabel? Block
1211static AstNode *ast_parse_block_expr(ParseContext *pc) {1185static AstNode *ast_parse_block_expr(ParseContext *pc) {
1212 Token *label = ast_parse_block_label(pc);1186 TokenIndex label = ast_parse_block_label(pc);
1213 if (label != nullptr) {1187 if (label != 0) {
1214 AstNode *res = ast_expect(pc, ast_parse_block);1188 AstNode *res = ast_expect(pc, ast_parse_block);
1215 assert(res->type == NodeTypeBlock);1189 assert(res->type == NodeTypeBlock);
1216 res->data.block.name = token_buf(label);1190 res->data.block.name = token_buf(pc, label);
1217 return res;1191 return res;
1218 }1192 }
12191193
...@@ -1230,8 +1204,8 @@ static AstNode *ast_parse_expr(ParseContext *pc) {...@@ -1230,8 +1204,8 @@ static AstNode *ast_parse_expr(ParseContext *pc) {
1230 return ast_parse_prefix_op_expr(1204 return ast_parse_prefix_op_expr(
1231 pc,1205 pc,
1232 [](ParseContext *context) {1206 [](ParseContext *context) {
1233 Token *try_token = eat_token_if(context, TokenIdKeywordTry);1207 TokenIndex try_token = eat_token_if(context, TokenIdKeywordTry);
1234 if (try_token != nullptr) {1208 if (try_token != 0) {
1235 AstNode *res = ast_create_node(context, NodeTypeReturnExpr, try_token);1209 AstNode *res = ast_create_node(context, NodeTypeReturnExpr, try_token);
1236 res->data.return_expr.kind = ReturnKindError;1210 res->data.return_expr.kind = ReturnKindError;
1237 return res;1211 return res;
...@@ -1318,72 +1292,72 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc) {...@@ -1318,72 +1292,72 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc) {
1318 if (if_expr != nullptr)1292 if (if_expr != nullptr)
1319 return if_expr;1293 return if_expr;
13201294
1321 Token *break_token = eat_token_if(pc, TokenIdKeywordBreak);1295 TokenIndex break_token = eat_token_if(pc, TokenIdKeywordBreak);
1322 if (break_token != nullptr) {1296 if (break_token != 0) {
1323 Token *label = ast_parse_break_label(pc);1297 TokenIndex label = ast_parse_break_label(pc);
1324 AstNode *expr = ast_parse_expr(pc);1298 AstNode *expr = ast_parse_expr(pc);
13251299
1326 AstNode *res = ast_create_node(pc, NodeTypeBreak, break_token);1300 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);
1328 res->data.break_expr.expr = expr;1302 res->data.break_expr.expr = expr;
1329 return res;1303 return res;
1330 }1304 }
13311305
1332 Token *comptime = eat_token_if(pc, TokenIdKeywordCompTime);1306 TokenIndex comptime = eat_token_if(pc, TokenIdKeywordCompTime);
1333 if (comptime != nullptr) {1307 if (comptime != 0) {
1334 AstNode *expr = ast_expect(pc, ast_parse_expr);1308 AstNode *expr = ast_expect(pc, ast_parse_expr);
1335 AstNode *res = ast_create_node(pc, NodeTypeCompTime, comptime);1309 AstNode *res = ast_create_node(pc, NodeTypeCompTime, comptime);
1336 res->data.comptime_expr.expr = expr;1310 res->data.comptime_expr.expr = expr;
1337 return res;1311 return res;
1338 }1312 }
13391313
1340 Token *nosuspend = eat_token_if(pc, TokenIdKeywordNoSuspend);1314 TokenIndex nosuspend = eat_token_if(pc, TokenIdKeywordNoSuspend);
1341 if (nosuspend != nullptr) {1315 if (nosuspend != 0) {
1342 AstNode *expr = ast_expect(pc, ast_parse_expr);1316 AstNode *expr = ast_expect(pc, ast_parse_expr);
1343 AstNode *res = ast_create_node(pc, NodeTypeNoSuspend, nosuspend);1317 AstNode *res = ast_create_node(pc, NodeTypeNoSuspend, nosuspend);
1344 res->data.nosuspend_expr.expr = expr;1318 res->data.nosuspend_expr.expr = expr;
1345 return res;1319 return res;
1346 }1320 }
13471321
1348 Token *continue_token = eat_token_if(pc, TokenIdKeywordContinue);1322 TokenIndex continue_token = eat_token_if(pc, TokenIdKeywordContinue);
1349 if (continue_token != nullptr) {1323 if (continue_token != 0) {
1350 Token *label = ast_parse_break_label(pc);1324 TokenIndex label = ast_parse_break_label(pc);
1351 AstNode *res = ast_create_node(pc, NodeTypeContinue, continue_token);1325 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);
1353 return res;1327 return res;
1354 }1328 }
13551329
1356 Token *resume = eat_token_if(pc, TokenIdKeywordResume);1330 TokenIndex resume = eat_token_if(pc, TokenIdKeywordResume);
1357 if (resume != nullptr) {1331 if (resume != 0) {
1358 AstNode *expr = ast_expect(pc, ast_parse_expr);1332 AstNode *expr = ast_expect(pc, ast_parse_expr);
1359 AstNode *res = ast_create_node(pc, NodeTypeResume, resume);1333 AstNode *res = ast_create_node(pc, NodeTypeResume, resume);
1360 res->data.resume_expr.expr = expr;1334 res->data.resume_expr.expr = expr;
1361 return res;1335 return res;
1362 }1336 }
13631337
1364 Token *return_token = eat_token_if(pc, TokenIdKeywordReturn);1338 TokenIndex return_token = eat_token_if(pc, TokenIdKeywordReturn);
1365 if (return_token != nullptr) {1339 if (return_token != 0) {
1366 AstNode *expr = ast_parse_expr(pc);1340 AstNode *expr = ast_parse_expr(pc);
1367 AstNode *res = ast_create_node(pc, NodeTypeReturnExpr, return_token);1341 AstNode *res = ast_create_node(pc, NodeTypeReturnExpr, return_token);
1368 res->data.return_expr.expr = expr;1342 res->data.return_expr.expr = expr;
1369 return res;1343 return res;
1370 }1344 }
13711345
1372 Token *label = ast_parse_block_label(pc);1346 TokenIndex label = ast_parse_block_label(pc);
1373 AstNode *loop = ast_parse_loop_expr(pc);1347 AstNode *loop = ast_parse_loop_expr(pc);
1374 if (loop != nullptr) {1348 if (loop != nullptr) {
1375 switch (loop->type) {1349 switch (loop->type) {
1376 case NodeTypeForExpr:1350 case NodeTypeForExpr:
1377 loop->data.for_expr.name = token_buf(label);1351 loop->data.for_expr.name = token_buf(pc, label);
1378 break;1352 break;
1379 case NodeTypeWhileExpr:1353 case NodeTypeWhileExpr:
1380 loop->data.while_expr.name = token_buf(label);1354 loop->data.while_expr.name = token_buf(pc, label);
1381 break;1355 break;
1382 default:1356 default:
1383 zig_unreachable();1357 zig_unreachable();
1384 }1358 }
1385 return loop;1359 return loop;
1386 } else if (label != nullptr) {1360 } else if (label != 0) {
1387 // Restore the tokens that we eaten by ast_parse_block_label.1361 // Restore the tokens that we eaten by ast_parse_block_label.
1388 put_back_token(pc);1362 put_back_token(pc);
1389 put_back_token(pc);1363 put_back_token(pc);
...@@ -1407,8 +1381,8 @@ static AstNode *ast_parse_if_expr(ParseContext *pc) {...@@ -1407,8 +1381,8 @@ static AstNode *ast_parse_if_expr(ParseContext *pc) {
14071381
1408// Block <- LBRACE Statement* RBRACE1382// Block <- LBRACE Statement* RBRACE
1409static AstNode *ast_parse_block(ParseContext *pc) {1383static AstNode *ast_parse_block(ParseContext *pc) {
1410 Token *lbrace = eat_token_if(pc, TokenIdLBrace);1384 TokenIndex lbrace = eat_token_if(pc, TokenIdLBrace);
1411 if (lbrace == nullptr)1385 if (lbrace == 0)
1412 return nullptr;1386 return nullptr;
14131387
1414 ZigList<AstNode *> statements = {};1388 ZigList<AstNode *> statements = {};
...@@ -1462,8 +1436,8 @@ static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc) {...@@ -1462,8 +1436,8 @@ static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc) {
1462// / LBRACE Expr (COMMA Expr)* COMMA? RBRACE1436// / LBRACE Expr (COMMA Expr)* COMMA? RBRACE
1463// / LBRACE RBRACE1437// / LBRACE RBRACE
1464static AstNode *ast_parse_init_list(ParseContext *pc) {1438static AstNode *ast_parse_init_list(ParseContext *pc) {
1465 Token *lbrace = eat_token_if(pc, TokenIdLBrace);1439 TokenIndex lbrace = eat_token_if(pc, TokenIdLBrace);
1466 if (lbrace == nullptr)1440 if (lbrace == 0)
1467 return nullptr;1441 return nullptr;
14681442
1469 AstNode *first = ast_parse_field_init(pc);1443 AstNode *first = ast_parse_field_init(pc);
...@@ -1472,7 +1446,7 @@ static AstNode *ast_parse_init_list(ParseContext *pc) {...@@ -1472,7 +1446,7 @@ static AstNode *ast_parse_init_list(ParseContext *pc) {
1472 res->data.container_init_expr.kind = ContainerInitKindStruct;1446 res->data.container_init_expr.kind = ContainerInitKindStruct;
1473 res->data.container_init_expr.entries.append(first);1447 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) {
1476 AstNode *field_init = ast_parse_field_init(pc);1450 AstNode *field_init = ast_parse_field_init(pc);
1477 if (field_init == nullptr)1451 if (field_init == nullptr)
1478 break;1452 break;
...@@ -1490,7 +1464,7 @@ static AstNode *ast_parse_init_list(ParseContext *pc) {...@@ -1490,7 +1464,7 @@ static AstNode *ast_parse_init_list(ParseContext *pc) {
1490 if (first != nullptr) {1464 if (first != nullptr) {
1491 res->data.container_init_expr.entries.append(first);1465 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) {
1494 AstNode *expr = ast_parse_expr(pc);1468 AstNode *expr = ast_parse_expr(pc);
1495 if (expr == nullptr)1469 if (expr == nullptr)
1496 break;1470 break;
...@@ -1535,7 +1509,7 @@ static AstNode *ast_parse_error_union_expr(ParseContext *pc) {...@@ -1535,7 +1509,7 @@ static AstNode *ast_parse_error_union_expr(ParseContext *pc) {
1535// <- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments1509// <- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments
1536// / PrimaryTypeExpr (SuffixOp / FnCallArguments)*1510// / PrimaryTypeExpr (SuffixOp / FnCallArguments)*
1537static AstNode *ast_parse_suffix_expr(ParseContext *pc) {1511static 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);
1539 if (async_token) {1513 if (async_token) {
1540 AstNode *child = ast_expect(pc, ast_parse_primary_type_expr);1514 AstNode *child = ast_expect(pc, ast_parse_primary_type_expr);
1541 while (true) {1515 while (true) {
...@@ -1652,43 +1626,21 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) {...@@ -1652,43 +1626,21 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
1652// / STRINGLITERAL1626// / STRINGLITERAL
1653// / SwitchExpr1627// / SwitchExpr
1654static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {1628static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
1655 // TODO: This is not in line with the grammar.1629 TokenIndex builtin_tok = eat_token_if(pc, TokenIdBuiltin);
1656 // Because the prev stage 1 tokenizer does not parse1630 if (builtin_tok != 0) {
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
1675 AstNode *res = ast_expect(pc, ast_parse_fn_call_arguments);1631 AstNode *res = ast_expect(pc, ast_parse_fn_call_arguments);
1676 AstNode *name_sym = ast_create_node(pc, NodeTypeSymbol, token);1632 AstNode *name_sym = ast_create_node(pc, NodeTypeIdentifier, builtin_tok);
1677 name_sym->data.symbol_expr.symbol = name;
16781633
1679 assert(res->type == NodeTypeFnCallExpr);1634 assert(res->type == NodeTypeFnCallExpr);
1680 res->line = at_sign->start_line;1635 res->main_token = builtin_tok;
1681 res->column = at_sign->start_column;
1682 res->data.fn_call_expr.fn_ref_expr = name_sym;1636 res->data.fn_call_expr.fn_ref_expr = name_sym;
1683 res->data.fn_call_expr.modifier = CallModifierBuiltin;1637 res->data.fn_call_expr.modifier = CallModifierBuiltin;
1684 return res;1638 return res;
1685 }1639 }
16861640
1687 Token *char_lit = eat_token_if(pc, TokenIdCharLiteral);1641 TokenIndex char_lit = eat_token_if(pc, TokenIdCharLiteral);
1688 if (char_lit != nullptr) {1642 if (char_lit != 0) {
1689 AstNode *res = ast_create_node(pc, NodeTypeCharLiteral, char_lit);1643 return ast_create_node(pc, NodeTypeCharLiteral, char_lit);
1690 res->data.char_literal.value = char_lit->data.char_lit.c;
1691 return res;
1692 }1644 }
16931645
1694 AstNode *container_decl = ast_parse_container_decl(pc);1646 AstNode *container_decl = ast_parse_container_decl(pc);
...@@ -1703,12 +1655,9 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {...@@ -1703,12 +1655,9 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
1703 if (error_set_decl != nullptr)1655 if (error_set_decl != nullptr)
1704 return error_set_decl;1656 return error_set_decl;
17051657
1706 Token *float_lit = eat_token_if(pc, TokenIdFloatLiteral);1658 TokenIndex float_lit = eat_token_if(pc, TokenIdFloatLiteral);
1707 if (float_lit != nullptr) {1659 if (float_lit != 0) {
1708 AstNode *res = ast_create_node(pc, NodeTypeFloatLiteral, float_lit);1660 return 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;
1712 }1661 }
17131662
1714 AstNode *fn_proto = ast_parse_fn_proto(pc);1663 AstNode *fn_proto = ast_parse_fn_proto(pc);
...@@ -1723,86 +1672,77 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {...@@ -1723,86 +1672,77 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
1723 if (labeled_type_expr != nullptr)1672 if (labeled_type_expr != nullptr)
1724 return labeled_type_expr;1673 return labeled_type_expr;
17251674
1726 Token *identifier = eat_token_if(pc, TokenIdSymbol);1675 TokenIndex identifier = eat_token_if(pc, TokenIdIdentifier);
1727 if (identifier != nullptr)1676 if (identifier != 0)
1728 return token_symbol(pc, identifier);1677 return token_identifier(pc, identifier);
17291678
1730 AstNode *if_type_expr = ast_parse_if_type_expr(pc);1679 AstNode *if_type_expr = ast_parse_if_type_expr(pc);
1731 if (if_type_expr != nullptr)1680 if (if_type_expr != nullptr)
1732 return if_type_expr;1681 return if_type_expr;
17331682
1734 Token *int_lit = eat_token_if(pc, TokenIdIntLiteral);1683 TokenIndex int_lit = eat_token_if(pc, TokenIdIntLiteral);
1735 if (int_lit != nullptr) {1684 if (int_lit != 0) {
1736 AstNode *res = ast_create_node(pc, NodeTypeIntLiteral, int_lit);1685 return ast_create_node(pc, NodeTypeIntLiteral, int_lit);
1737 res->data.int_literal.bigint = &int_lit->data.int_lit.bigint;
1738 return res;
1739 }1686 }
17401687
1741 Token *comptime = eat_token_if(pc, TokenIdKeywordCompTime);1688 TokenIndex comptime = eat_token_if(pc, TokenIdKeywordCompTime);
1742 if (comptime != nullptr) {1689 if (comptime != 0) {
1743 AstNode *expr = ast_expect(pc, ast_parse_type_expr);1690 AstNode *expr = ast_expect(pc, ast_parse_type_expr);
1744 AstNode *res = ast_create_node(pc, NodeTypeCompTime, comptime);1691 AstNode *res = ast_create_node(pc, NodeTypeCompTime, comptime);
1745 res->data.comptime_expr.expr = expr;1692 res->data.comptime_expr.expr = expr;
1746 return res;1693 return res;
1747 }1694 }
17481695
1749 Token *error = eat_token_if(pc, TokenIdKeywordError);1696 TokenIndex error = eat_token_if(pc, TokenIdKeywordError);
1750 if (error != nullptr) {1697 if (error != 0) {
1751 Token *dot = expect_token(pc, TokenIdDot);1698 TokenIndex dot = expect_token(pc, TokenIdDot);
1752 Token *name = expect_token(pc, TokenIdSymbol);1699 TokenIndex name = expect_token(pc, TokenIdIdentifier);
1753 AstNode *left = ast_create_node(pc, NodeTypeErrorType, error);1700 AstNode *left = ast_create_node(pc, NodeTypeErrorType, error);
1754 AstNode *res = ast_create_node(pc, NodeTypeFieldAccessExpr, dot);1701 AstNode *res = ast_create_node(pc, NodeTypeFieldAccessExpr, dot);
1755 res->data.field_access_expr.struct_expr = left;1702 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);
1757 return res;1704 return res;
1758 }1705 }
17591706
1760 Token *false_token = eat_token_if(pc, TokenIdKeywordFalse);1707 TokenIndex false_token = eat_token_if(pc, TokenIdKeywordFalse);
1761 if (false_token != nullptr) {1708 if (false_token != 0) {
1762 AstNode *res = ast_create_node(pc, NodeTypeBoolLiteral, false_token);1709 AstNode *res = ast_create_node(pc, NodeTypeBoolLiteral, false_token);
1763 res->data.bool_literal.value = false;1710 res->data.bool_literal.value = false;
1764 return res;1711 return res;
1765 }1712 }
17661713
1767 Token *null = eat_token_if(pc, TokenIdKeywordNull);1714 TokenIndex null = eat_token_if(pc, TokenIdKeywordNull);
1768 if (null != nullptr)1715 if (null != 0)
1769 return ast_create_node(pc, NodeTypeNullLiteral, null);1716 return ast_create_node(pc, NodeTypeNullLiteral, null);
17701717
1771 Token *anyframe = eat_token_if(pc, TokenIdKeywordAnyFrame);1718 TokenIndex anyframe = eat_token_if(pc, TokenIdKeywordAnyFrame);
1772 if (anyframe != nullptr)1719 if (anyframe != 0)
1773 return ast_create_node(pc, NodeTypeAnyFrameType, anyframe);1720 return ast_create_node(pc, NodeTypeAnyFrameType, anyframe);
17741721
1775 Token *true_token = eat_token_if(pc, TokenIdKeywordTrue);1722 TokenIndex true_token = eat_token_if(pc, TokenIdKeywordTrue);
1776 if (true_token != nullptr) {1723 if (true_token != 0) {
1777 AstNode *res = ast_create_node(pc, NodeTypeBoolLiteral, true_token);1724 AstNode *res = ast_create_node(pc, NodeTypeBoolLiteral, true_token);
1778 res->data.bool_literal.value = true;1725 res->data.bool_literal.value = true;
1779 return res;1726 return res;
1780 }1727 }
17811728
1782 Token *undefined = eat_token_if(pc, TokenIdKeywordUndefined);1729 TokenIndex undefined = eat_token_if(pc, TokenIdKeywordUndefined);
1783 if (undefined != nullptr)1730 if (undefined != 0)
1784 return ast_create_node(pc, NodeTypeUndefinedLiteral, undefined);1731 return ast_create_node(pc, NodeTypeUndefinedLiteral, undefined);
17851732
1786 Token *unreachable = eat_token_if(pc, TokenIdKeywordUnreachable);1733 TokenIndex unreachable = eat_token_if(pc, TokenIdKeywordUnreachable);
1787 if (unreachable != nullptr)1734 if (unreachable != 0)
1788 return ast_create_node(pc, NodeTypeUnreachable, unreachable);1735 return ast_create_node(pc, NodeTypeUnreachable, unreachable);
17891736
17901737
1791 Buf *string_buf;1738 TokenIndex string_lit = eat_token_if(pc, TokenIdStringLiteral);
1792 Token *string_lit = eat_token_if(pc, TokenIdStringLiteral);1739 if (string_lit != 0) {
1793 if (string_lit != nullptr) {1740 return ast_create_node(pc, NodeTypeStringLiteral, string_lit);
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 }
1801 }1741 }
1802 if (string_lit != nullptr) {1742
1803 AstNode *res = ast_create_node(pc, NodeTypeStringLiteral, string_lit);1743 TokenIndex multiline_str_lit = ast_parse_multi_tok(pc, TokenIdMultilineStringLiteralLine);
1804 res->data.string_literal.buf = string_buf;1744 if (multiline_str_lit != 0) {
1805 return res;1745 return ast_create_node(pc, NodeTypeStringLiteral, multiline_str_lit);
1806 }1746 }
18071747
1808 AstNode *switch_expr = ast_parse_switch_expr(pc);1748 AstNode *switch_expr = ast_parse_switch_expr(pc);
...@@ -1814,22 +1754,21 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {...@@ -1814,22 +1754,21 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
18141754
1815// ContainerDecl <- (KEYWORD_extern / KEYWORD_packed)? ContainerDeclAuto1755// ContainerDecl <- (KEYWORD_extern / KEYWORD_packed)? ContainerDeclAuto
1816static AstNode *ast_parse_container_decl(ParseContext *pc) {1756static AstNode *ast_parse_container_decl(ParseContext *pc) {
1817 Token *layout_token = eat_token_if(pc, TokenIdKeywordExtern);1757 TokenIndex layout_token = eat_token_if(pc, TokenIdKeywordExtern);
1818 if (layout_token == nullptr)1758 if (layout_token == 0)
1819 layout_token = eat_token_if(pc, TokenIdKeywordPacked);1759 layout_token = eat_token_if(pc, TokenIdKeywordPacked);
18201760
1821 AstNode *res = ast_parse_container_decl_auto(pc);1761 AstNode *res = ast_parse_container_decl_auto(pc);
1822 if (res == nullptr) {1762 if (res == nullptr) {
1823 if (layout_token != nullptr)1763 if (layout_token != 0)
1824 put_back_token(pc);1764 put_back_token(pc);
1825 return nullptr;1765 return nullptr;
1826 }1766 }
18271767
1828 assert(res->type == NodeTypeContainerDecl);1768 assert(res->type == NodeTypeContainerDecl);
1829 if (layout_token != nullptr) {1769 if (layout_token != 0) {
1830 res->line = layout_token->start_line;1770 res->main_token = layout_token;
1831 res->column = layout_token->start_column;1771 res->data.container_decl.layout = pc->token_ids[layout_token] == TokenIdKeywordExtern
1832 res->data.container_decl.layout = layout_token->id == TokenIdKeywordExtern
1833 ? ContainerLayoutExtern1772 ? ContainerLayoutExtern
1834 : ContainerLayoutPacked;1773 : ContainerLayoutPacked;
1835 }1774 }
...@@ -1838,28 +1777,27 @@ static AstNode *ast_parse_container_decl(ParseContext *pc) {...@@ -1838,28 +1777,27 @@ static AstNode *ast_parse_container_decl(ParseContext *pc) {
18381777
1839// ErrorSetDecl <- KEYWORD_error LBRACE IdentifierList RBRACE1778// ErrorSetDecl <- KEYWORD_error LBRACE IdentifierList RBRACE
1840static AstNode *ast_parse_error_set_decl(ParseContext *pc) {1779static AstNode *ast_parse_error_set_decl(ParseContext *pc) {
1841 Token *first = eat_token_if(pc, TokenIdKeywordError);1780 TokenIndex first = eat_token_if(pc, TokenIdKeywordError);
1842 if (first == nullptr)1781 if (first == 0)
1843 return nullptr;1782 return nullptr;
1844 if (eat_token_if(pc, TokenIdLBrace) == nullptr) {1783 if (eat_token_if(pc, TokenIdLBrace) == 0) {
1845 put_back_token(pc);1784 put_back_token(pc);
1846 return nullptr;1785 return nullptr;
1847 }1786 }
18481787
1849 ZigList<AstNode *> decls = ast_parse_list<AstNode>(pc, TokenIdComma, [](ParseContext *context) {1788 ZigList<AstNode *> decls = ast_parse_list<AstNode>(pc, TokenIdComma, [](ParseContext *context) {
1850 Buf doc_comment_buf = BUF_INIT;1789 TokenIndex doc_token = ast_parse_doc_comments(context);
1851 Token *doc_token = ast_parse_doc_comments(context, &doc_comment_buf);1790 TokenIndex ident = eat_token_if(context, TokenIdIdentifier);
1852 Token *ident = eat_token_if(context, TokenIdSymbol);1791 if (ident == 0)
1853 if (ident == nullptr)
1854 return (AstNode*)nullptr;1792 return (AstNode*)nullptr;
18551793
1856 AstNode *symbol_node = token_symbol(context, ident);1794 AstNode *symbol_node = token_identifier(context, ident);
1857 if (doc_token == nullptr)1795 if (doc_token == 0)
1858 return symbol_node;1796 return symbol_node;
18591797
1860 AstNode *field_node = ast_create_node(context, NodeTypeErrorSetField, doc_token);1798 AstNode *field_node = ast_create_node(context, NodeTypeErrorSetField, doc_token);
1861 field_node->data.err_set_field.field_name = symbol_node;1799 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;
1863 return field_node;1801 return field_node;
1864 });1802 });
1865 expect_token(pc, TokenIdRBrace);1803 expect_token(pc, TokenIdRBrace);
...@@ -1871,8 +1809,8 @@ static AstNode *ast_parse_error_set_decl(ParseContext *pc) {...@@ -1871,8 +1809,8 @@ static AstNode *ast_parse_error_set_decl(ParseContext *pc) {
18711809
1872// GroupedExpr <- LPAREN Expr RPAREN1810// GroupedExpr <- LPAREN Expr RPAREN
1873static AstNode *ast_parse_grouped_expr(ParseContext *pc) {1811static AstNode *ast_parse_grouped_expr(ParseContext *pc) {
1874 Token *lparen = eat_token_if(pc, TokenIdLParen);1812 TokenIndex lparen = eat_token_if(pc, TokenIdLParen);
1875 if (lparen == nullptr)1813 if (lparen == 0)
1876 return nullptr;1814 return nullptr;
18771815
1878 AstNode *expr = ast_expect(pc, ast_parse_expr);1816 AstNode *expr = ast_expect(pc, ast_parse_expr);
...@@ -1892,12 +1830,12 @@ static AstNode *ast_parse_if_type_expr(ParseContext *pc) {...@@ -1892,12 +1830,12 @@ static AstNode *ast_parse_if_type_expr(ParseContext *pc) {
1892// <- BlockLabel Block1830// <- BlockLabel Block
1893// / BlockLabel? LoopTypeExpr1831// / BlockLabel? LoopTypeExpr
1894static AstNode *ast_parse_labeled_type_expr(ParseContext *pc) {1832static AstNode *ast_parse_labeled_type_expr(ParseContext *pc) {
1895 Token *label = ast_parse_block_label(pc);1833 TokenIndex label = ast_parse_block_label(pc);
1896 if (label != nullptr) {1834 if (label != 0) {
1897 AstNode *block = ast_parse_block(pc);1835 AstNode *block = ast_parse_block(pc);
1898 if (block != nullptr) {1836 if (block != nullptr) {
1899 assert(block->type == NodeTypeBlock);1837 assert(block->type == NodeTypeBlock);
1900 block->data.block.name = token_buf(label);1838 block->data.block.name = token_buf(pc, label);
1901 return block;1839 return block;
1902 }1840 }
1903 }1841 }
...@@ -1906,10 +1844,10 @@ static AstNode *ast_parse_labeled_type_expr(ParseContext *pc) {...@@ -1906,10 +1844,10 @@ static AstNode *ast_parse_labeled_type_expr(ParseContext *pc) {
1906 if (loop != nullptr) {1844 if (loop != nullptr) {
1907 switch (loop->type) {1845 switch (loop->type) {
1908 case NodeTypeForExpr:1846 case NodeTypeForExpr:
1909 loop->data.for_expr.name = token_buf(label);1847 loop->data.for_expr.name = token_buf(pc, label);
1910 break;1848 break;
1911 case NodeTypeWhileExpr:1849 case NodeTypeWhileExpr:
1912 loop->data.while_expr.name = token_buf(label);1850 loop->data.while_expr.name = token_buf(pc, label);
1913 break;1851 break;
1914 default:1852 default:
1915 zig_unreachable();1853 zig_unreachable();
...@@ -1917,7 +1855,7 @@ static AstNode *ast_parse_labeled_type_expr(ParseContext *pc) {...@@ -1917,7 +1855,7 @@ static AstNode *ast_parse_labeled_type_expr(ParseContext *pc) {
1917 return loop;1855 return loop;
1918 }1856 }
19191857
1920 if (label != nullptr) {1858 if (label != 0) {
1921 put_back_token(pc);1859 put_back_token(pc);
1922 put_back_token(pc);1860 put_back_token(pc);
1923 }1861 }
...@@ -1945,8 +1883,8 @@ static AstNode *ast_parse_while_type_expr(ParseContext *pc) {...@@ -1945,8 +1883,8 @@ static AstNode *ast_parse_while_type_expr(ParseContext *pc) {
19451883
1946// SwitchExpr <- KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE1884// SwitchExpr <- KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE
1947static AstNode *ast_parse_switch_expr(ParseContext *pc) {1885static AstNode *ast_parse_switch_expr(ParseContext *pc) {
1948 Token *switch_token = eat_token_if(pc, TokenIdKeywordSwitch);1886 TokenIndex switch_token = eat_token_if(pc, TokenIdKeywordSwitch);
1949 if (switch_token == nullptr)1887 if (switch_token == 0)
1950 return nullptr;1888 return nullptr;
19511889
1952 expect_token(pc, TokenIdLParen);1890 expect_token(pc, TokenIdLParen);
...@@ -1964,11 +1902,11 @@ static AstNode *ast_parse_switch_expr(ParseContext *pc) {...@@ -1964,11 +1902,11 @@ static AstNode *ast_parse_switch_expr(ParseContext *pc) {
19641902
1965// AsmExpr <- KEYWORD_asm KEYWORD_volatile? LPAREN STRINGLITERAL AsmOutput? RPAREN1903// AsmExpr <- KEYWORD_asm KEYWORD_volatile? LPAREN STRINGLITERAL AsmOutput? RPAREN
1966static AstNode *ast_parse_asm_expr(ParseContext *pc) {1904static AstNode *ast_parse_asm_expr(ParseContext *pc) {
1967 Token *asm_token = eat_token_if(pc, TokenIdKeywordAsm);1905 TokenIndex asm_token = eat_token_if(pc, TokenIdKeywordAsm);
1968 if (asm_token == nullptr)1906 if (asm_token == 0)
1969 return nullptr;1907 return nullptr;
19701908
1971 Token *volatile_token = eat_token_if(pc, TokenIdKeywordVolatile);1909 TokenIndex volatile_token = eat_token_if(pc, TokenIdKeywordVolatile);
1972 expect_token(pc, TokenIdLParen);1910 expect_token(pc, TokenIdLParen);
1973 AstNode *asm_template = ast_expect(pc, ast_parse_expr);1911 AstNode *asm_template = ast_expect(pc, ast_parse_expr);
1974 AstNode *res = ast_parse_asm_output(pc);1912 AstNode *res = ast_parse_asm_output(pc);
...@@ -1976,25 +1914,21 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc) {...@@ -1976,25 +1914,21 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc) {
1976 res = ast_create_node_no_line_info(pc, NodeTypeAsmExpr);1914 res = ast_create_node_no_line_info(pc, NodeTypeAsmExpr);
1977 expect_token(pc, TokenIdRParen);1915 expect_token(pc, TokenIdRParen);
19781916
1979 res->line = asm_token->start_line;1917 res->main_token = asm_token;
1980 res->column = asm_token->start_column;
1981 res->data.asm_expr.volatile_token = volatile_token;1918 res->data.asm_expr.volatile_token = volatile_token;
1982 res->data.asm_expr.asm_template = asm_template;1919 res->data.asm_expr.asm_template = asm_template;
1983 return res;1920 return res;
1984}1921}
19851922
1986static AstNode *ast_parse_anon_lit(ParseContext *pc) {1923static AstNode *ast_parse_anon_lit(ParseContext *pc) {
1987 Token *period = eat_token_if(pc, TokenIdDot);1924 TokenIndex period = eat_token_if(pc, TokenIdDot);
1988 if (period == nullptr)1925 if (period == 0)
1989 return nullptr;1926 return nullptr;
19901927
1991 // anon enum literal1928 // anon enum literal
1992 Token *identifier = eat_token_if(pc, TokenIdSymbol);1929 TokenIndex identifier = eat_token_if(pc, TokenIdIdentifier);
1993 if (identifier != nullptr) {1930 if (identifier != 0) {
1994 AstNode *res = ast_create_node(pc, NodeTypeEnumLiteral, period);1931 return ast_create_node(pc, NodeTypeEnumLiteral, period);
1995 res->data.enum_literal.period = period;
1996 res->data.enum_literal.identifier = identifier;
1997 return res;
1998 }1932 }
19991933
2000 // anon container literal1934 // anon container literal
...@@ -2007,7 +1941,7 @@ static AstNode *ast_parse_anon_lit(ParseContext *pc) {...@@ -2007,7 +1941,7 @@ static AstNode *ast_parse_anon_lit(ParseContext *pc) {
20071941
2008// AsmOutput <- COLON AsmOutputList AsmInput?1942// AsmOutput <- COLON AsmOutputList AsmInput?
2009static AstNode *ast_parse_asm_output(ParseContext *pc) {1943static AstNode *ast_parse_asm_output(ParseContext *pc) {
2010 if (eat_token_if(pc, TokenIdColon) == nullptr)1944 if (eat_token_if(pc, TokenIdColon) == 0)
2011 return nullptr;1945 return nullptr;
20121946
2013 ZigList<AsmOutput *> output_list = ast_parse_list(pc, TokenIdComma, ast_parse_asm_output_item);1947 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) {...@@ -2021,20 +1955,20 @@ static AstNode *ast_parse_asm_output(ParseContext *pc) {
20211955
2022// AsmOutputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr / IDENTIFIER) RPAREN1956// AsmOutputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr / IDENTIFIER) RPAREN
2023static AsmOutput *ast_parse_asm_output_item(ParseContext *pc) {1957static AsmOutput *ast_parse_asm_output_item(ParseContext *pc) {
2024 if (eat_token_if(pc, TokenIdLBracket) == nullptr)1958 if (eat_token_if(pc, TokenIdLBracket) == 0)
2025 return nullptr;1959 return nullptr;
20261960
2027 Token *sym_name = expect_token(pc, TokenIdSymbol);1961 TokenIndex sym_name = expect_token(pc, TokenIdIdentifier);
2028 expect_token(pc, TokenIdRBracket);1962 expect_token(pc, TokenIdRBracket);
20291963
2030 Token *str = eat_token_if(pc, TokenIdMultilineStringLiteral);1964 TokenIndex str = ast_parse_multi_tok(pc, TokenIdMultilineStringLiteralLine);
2031 if (str == nullptr)1965 if (str == 0)
2032 str = expect_token(pc, TokenIdStringLiteral);1966 str = expect_token(pc, TokenIdStringLiteral);
2033 expect_token(pc, TokenIdLParen);1967 expect_token(pc, TokenIdLParen);
20341968
2035 Token *var_name = eat_token_if(pc, TokenIdSymbol);1969 TokenIndex var_name = eat_token_if(pc, TokenIdIdentifier);
2036 AstNode *return_type = nullptr;1970 AstNode *return_type = nullptr;
2037 if (var_name == nullptr) {1971 if (var_name == 0) {
2038 expect_token(pc, TokenIdArrow);1972 expect_token(pc, TokenIdArrow);
2039 return_type = ast_expect(pc, ast_parse_type_expr);1973 return_type = ast_expect(pc, ast_parse_type_expr);
2040 }1974 }
...@@ -2042,16 +1976,16 @@ static AsmOutput *ast_parse_asm_output_item(ParseContext *pc) {...@@ -2042,16 +1976,16 @@ static AsmOutput *ast_parse_asm_output_item(ParseContext *pc) {
2042 expect_token(pc, TokenIdRParen);1976 expect_token(pc, TokenIdRParen);
20431977
2044 AsmOutput *res = heap::c_allocator.create<AsmOutput>();1978 AsmOutput *res = heap::c_allocator.create<AsmOutput>();
2045 res->asm_symbolic_name = token_buf(sym_name);1979 res->asm_symbolic_name = token_buf(pc, sym_name);
2046 res->constraint = token_buf(str);1980 res->constraint = token_buf(pc, str);
2047 res->variable_name = token_buf(var_name);1981 res->variable_name = token_buf(pc, var_name);
2048 res->return_type = return_type;1982 res->return_type = return_type;
2049 return res;1983 return res;
2050}1984}
20511985
2052// AsmInput <- COLON AsmInputList AsmClobbers?1986// AsmInput <- COLON AsmInputList AsmClobbers?
2053static AstNode *ast_parse_asm_input(ParseContext *pc) {1987static AstNode *ast_parse_asm_input(ParseContext *pc) {
2054 if (eat_token_if(pc, TokenIdColon) == nullptr)1988 if (eat_token_if(pc, TokenIdColon) == 0)
2055 return nullptr;1989 return nullptr;
20561990
2057 ZigList<AsmInput *> input_list = ast_parse_list(pc, TokenIdComma, ast_parse_asm_input_item);1991 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) {...@@ -2065,37 +1999,35 @@ static AstNode *ast_parse_asm_input(ParseContext *pc) {
20651999
2066// AsmInputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN2000// AsmInputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN
2067static AsmInput *ast_parse_asm_input_item(ParseContext *pc) {2001static AsmInput *ast_parse_asm_input_item(ParseContext *pc) {
2068 if (eat_token_if(pc, TokenIdLBracket) == nullptr)2002 if (eat_token_if(pc, TokenIdLBracket) == 0)
2069 return nullptr;2003 return nullptr;
20702004
2071 Token *sym_name = expect_token(pc, TokenIdSymbol);2005 TokenIndex sym_name = expect_token(pc, TokenIdIdentifier);
2072 expect_token(pc, TokenIdRBracket);2006 expect_token(pc, TokenIdRBracket);
20732007
2074 Token *constraint = eat_token_if(pc, TokenIdMultilineStringLiteral);2008 TokenIndex constraint = expect_token(pc, TokenIdStringLiteral);
2075 if (constraint == nullptr)
2076 constraint = expect_token(pc, TokenIdStringLiteral);
2077 expect_token(pc, TokenIdLParen);2009 expect_token(pc, TokenIdLParen);
2078 AstNode *expr = ast_expect(pc, ast_parse_expr);2010 AstNode *expr = ast_expect(pc, ast_parse_expr);
2079 expect_token(pc, TokenIdRParen);2011 expect_token(pc, TokenIdRParen);
20802012
2081 AsmInput *res = heap::c_allocator.create<AsmInput>();2013 AsmInput *res = heap::c_allocator.create<AsmInput>();
2082 res->asm_symbolic_name = token_buf(sym_name);2014 res->asm_symbolic_name = token_buf(pc, sym_name);
2083 res->constraint = token_buf(constraint);2015 res->constraint = token_buf(pc, constraint);
2084 res->expr = expr;2016 res->expr = expr;
2085 return res;2017 return res;
2086}2018}
20872019
2088// AsmClobbers <- COLON StringList2020// AsmClobbers <- COLON StringList
2089static AstNode *ast_parse_asm_clobbers(ParseContext *pc) {2021static AstNode *ast_parse_asm_clobbers(ParseContext *pc) {
2090 if (eat_token_if(pc, TokenIdColon) == nullptr)2022 if (eat_token_if(pc, TokenIdColon) == 0)
2091 return nullptr;2023 return nullptr;
20922024
2093 ZigList<Buf *> clobber_list = ast_parse_list<Buf>(pc, TokenIdComma, [](ParseContext *context) {2025 ZigList<Buf *> clobber_list = ast_parse_list<Buf>(pc, TokenIdComma, [](ParseContext *context) {
2094 Token *str = eat_token_if(context, TokenIdStringLiteral);2026 TokenIndex str = eat_token_if(context, TokenIdStringLiteral);
2095 if (str == nullptr)2027 if (str == 0)
2096 str = eat_token_if(context, TokenIdMultilineStringLiteral);2028 str = ast_parse_multi_tok(context, TokenIdMultilineStringLiteralLine);
2097 if (str != nullptr)2029 if (str != 0)
2098 return token_buf(str);2030 return token_buf(context, str);
2099 return (Buf*)nullptr;2031 return (Buf*)nullptr;
2100 });2032 });
21012033
...@@ -2105,24 +2037,24 @@ static AstNode *ast_parse_asm_clobbers(ParseContext *pc) {...@@ -2105,24 +2037,24 @@ static AstNode *ast_parse_asm_clobbers(ParseContext *pc) {
2105}2037}
21062038
2107// BreakLabel <- COLON IDENTIFIER2039// BreakLabel <- COLON IDENTIFIER
2108static Token *ast_parse_break_label(ParseContext *pc) {2040static TokenIndex ast_parse_break_label(ParseContext *pc) {
2109 if (eat_token_if(pc, TokenIdColon) == nullptr)2041 if (eat_token_if(pc, TokenIdColon) == 0)
2110 return nullptr;2042 return 0;
21112043
2112 return expect_token(pc, TokenIdSymbol);2044 return expect_token(pc, TokenIdIdentifier);
2113}2045}
21142046
2115// BlockLabel <- IDENTIFIER COLON2047// BlockLabel <- IDENTIFIER COLON
2116static Token *ast_parse_block_label(ParseContext *pc) {2048static TokenIndex ast_parse_block_label(ParseContext *pc) {
2117 Token *ident = eat_token_if(pc, TokenIdSymbol);2049 TokenIndex ident = eat_token_if(pc, TokenIdIdentifier);
2118 if (ident == nullptr)2050 if (ident == 0)
2119 return nullptr;2051 return 0;
21202052
2121 // We do 2 token lookahead here, as we don't want to error when2053 // We do 2 token lookahead here, as we don't want to error when
2122 // parsing identifiers.2054 // parsing identifiers.
2123 if (eat_token_if(pc, TokenIdColon) == nullptr) {2055 if (eat_token_if(pc, TokenIdColon) == 0) {
2124 put_back_token(pc);2056 put_back_token(pc);
2125 return nullptr;2057 return 0;
2126 }2058 }
21272059
2128 return ident;2060 return ident;
...@@ -2130,17 +2062,17 @@ static Token *ast_parse_block_label(ParseContext *pc) {...@@ -2130,17 +2062,17 @@ static Token *ast_parse_block_label(ParseContext *pc) {
21302062
2131// FieldInit <- DOT IDENTIFIER EQUAL Expr2063// FieldInit <- DOT IDENTIFIER EQUAL Expr
2132static AstNode *ast_parse_field_init(ParseContext *pc) {2064static AstNode *ast_parse_field_init(ParseContext *pc) {
2133 Token *first = eat_token_if(pc, TokenIdDot);2065 TokenIndex first = eat_token_if(pc, TokenIdDot);
2134 if (first == nullptr)2066 if (first == 0)
2135 return nullptr;2067 return nullptr;
21362068
2137 Token *name = eat_token_if(pc, TokenIdSymbol);2069 TokenIndex name = eat_token_if(pc, TokenIdIdentifier);
2138 if (name == nullptr) {2070 if (name == 0) {
2139 // Because of anon literals ".{" is also valid.2071 // Because of anon literals ".{" is also valid.
2140 put_back_token(pc);2072 put_back_token(pc);
2141 return nullptr;2073 return nullptr;
2142 }2074 }
2143 if (eat_token_if(pc, TokenIdEq) == nullptr) {2075 if (eat_token_if(pc, TokenIdEq) == 0) {
2144 // Because ".Name" can also be intepreted as an enum literal, we should put back2076 // Because ".Name" can also be intepreted as an enum literal, we should put back
2145 // those two tokens again so that the parser can try to parse them as the enum2077 // those two tokens again so that the parser can try to parse them as the enum
2146 // literal later.2078 // literal later.
...@@ -2151,15 +2083,15 @@ static AstNode *ast_parse_field_init(ParseContext *pc) {...@@ -2151,15 +2083,15 @@ static AstNode *ast_parse_field_init(ParseContext *pc) {
2151 AstNode *expr = ast_expect(pc, ast_parse_expr);2083 AstNode *expr = ast_expect(pc, ast_parse_expr);
21522084
2153 AstNode *res = ast_create_node(pc, NodeTypeStructValueField, first);2085 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);
2155 res->data.struct_val_field.expr = expr;2087 res->data.struct_val_field.expr = expr;
2156 return res;2088 return res;
2157}2089}
21582090
2159// WhileContinueExpr <- COLON LPAREN AssignExpr RPAREN2091// WhileContinueExpr <- COLON LPAREN AssignExpr RPAREN
2160static AstNode *ast_parse_while_continue_expr(ParseContext *pc) {2092static AstNode *ast_parse_while_continue_expr(ParseContext *pc) {
2161 Token *first = eat_token_if(pc, TokenIdColon);2093 TokenIndex first = eat_token_if(pc, TokenIdColon);
2162 if (first == nullptr)2094 if (first == 0)
2163 return nullptr;2095 return nullptr;
21642096
2165 expect_token(pc, TokenIdLParen);2097 expect_token(pc, TokenIdLParen);
...@@ -2170,8 +2102,8 @@ static AstNode *ast_parse_while_continue_expr(ParseContext *pc) {...@@ -2170,8 +2102,8 @@ static AstNode *ast_parse_while_continue_expr(ParseContext *pc) {
21702102
2171// LinkSection <- KEYWORD_linksection LPAREN Expr RPAREN2103// LinkSection <- KEYWORD_linksection LPAREN Expr RPAREN
2172static AstNode *ast_parse_link_section(ParseContext *pc) {2104static AstNode *ast_parse_link_section(ParseContext *pc) {
2173 Token *first = eat_token_if(pc, TokenIdKeywordLinkSection);2105 TokenIndex first = eat_token_if(pc, TokenIdKeywordLinkSection);
2174 if (first == nullptr)2106 if (first == 0)
2175 return nullptr;2107 return nullptr;
21762108
2177 expect_token(pc, TokenIdLParen);2109 expect_token(pc, TokenIdLParen);
...@@ -2182,8 +2114,8 @@ static AstNode *ast_parse_link_section(ParseContext *pc) {...@@ -2182,8 +2114,8 @@ static AstNode *ast_parse_link_section(ParseContext *pc) {
21822114
2183// CallConv <- KEYWORD_callconv LPAREN Expr RPAREN2115// CallConv <- KEYWORD_callconv LPAREN Expr RPAREN
2184static AstNode *ast_parse_callconv(ParseContext *pc) {2116static AstNode *ast_parse_callconv(ParseContext *pc) {
2185 Token *first = eat_token_if(pc, TokenIdKeywordCallconv);2117 TokenIndex first = eat_token_if(pc, TokenIdKeywordCallconv);
2186 if (first == nullptr)2118 if (first == 0)
2187 return nullptr;2119 return nullptr;
21882120
2189 expect_token(pc, TokenIdLParen);2121 expect_token(pc, TokenIdLParen);
...@@ -2194,28 +2126,27 @@ static AstNode *ast_parse_callconv(ParseContext *pc) {...@@ -2194,28 +2126,27 @@ static AstNode *ast_parse_callconv(ParseContext *pc) {
21942126
2195// ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType2127// ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
2196static AstNode *ast_parse_param_decl(ParseContext *pc) {2128static AstNode *ast_parse_param_decl(ParseContext *pc) {
2197 Buf doc_comments = BUF_INIT;2129 TokenIndex first_doc_comment = ast_parse_doc_comments(pc);
2198 ast_parse_doc_comments(pc, &doc_comments);
21992130
2200 Token *first = eat_token_if(pc, TokenIdKeywordNoAlias);2131 TokenIndex first = eat_token_if(pc, TokenIdKeywordNoAlias);
2201 if (first == nullptr)2132 if (first == 0)
2202 first = eat_token_if(pc, TokenIdKeywordCompTime);2133 first = eat_token_if(pc, TokenIdKeywordCompTime);
22032134
2204 Token *name = eat_token_if(pc, TokenIdSymbol);2135 TokenIndex name = eat_token_if(pc, TokenIdIdentifier);
2205 if (name != nullptr) {2136 if (name != 0) {
2206 if (eat_token_if(pc, TokenIdColon) != nullptr) {2137 if (eat_token_if(pc, TokenIdColon) != 0) {
2207 if (first == nullptr)2138 if (first == 0)
2208 first = name;2139 first = name;
2209 } else {2140 } else {
2210 // We put back the ident, so it can be parsed as a ParamType2141 // We put back the ident, so it can be parsed as a ParamType
2211 // later.2142 // later.
2212 put_back_token(pc);2143 put_back_token(pc);
2213 name = nullptr;2144 name = 0;
2214 }2145 }
2215 }2146 }
22162147
2217 AstNode *res;2148 AstNode *res;
2218 if (first == nullptr) {2149 if (first == 0) {
2219 first = peek_token(pc);2150 first = peek_token(pc);
2220 res = ast_parse_param_type(pc);2151 res = ast_parse_param_type(pc);
2221 } else {2152 } else {
...@@ -2226,12 +2157,11 @@ static AstNode *ast_parse_param_decl(ParseContext *pc) {...@@ -2226,12 +2157,11 @@ static AstNode *ast_parse_param_decl(ParseContext *pc) {
2226 return nullptr;2157 return nullptr;
22272158
2228 assert(res->type == NodeTypeParamDecl);2159 assert(res->type == NodeTypeParamDecl);
2229 res->line = first->start_line;2160 res->main_token = first;
2230 res->column = first->start_column;2161 res->data.param_decl.name = token_buf(pc, name);
2231 res->data.param_decl.name = token_buf(name);2162 res->data.param_decl.doc_comments = first_doc_comment;
2232 res->data.param_decl.doc_comments = doc_comments;2163 res->data.param_decl.is_noalias = pc->token_ids[first] == TokenIdKeywordNoAlias;
2233 res->data.param_decl.is_noalias = first->id == TokenIdKeywordNoAlias;2164 res->data.param_decl.is_comptime = pc->token_ids[first] == TokenIdKeywordCompTime;
2234 res->data.param_decl.is_comptime = first->id == TokenIdKeywordCompTime;
2235 return res;2165 return res;
2236}2166}
22372167
...@@ -2240,15 +2170,15 @@ static AstNode *ast_parse_param_decl(ParseContext *pc) {...@@ -2240,15 +2170,15 @@ static AstNode *ast_parse_param_decl(ParseContext *pc) {
2240// / DOT32170// / DOT3
2241// / TypeExpr2171// / TypeExpr
2242static AstNode *ast_parse_param_type(ParseContext *pc) {2172static AstNode *ast_parse_param_type(ParseContext *pc) {
2243 Token *anytype_token = eat_token_if(pc, TokenIdKeywordAnyType);2173 TokenIndex anytype_token = eat_token_if(pc, TokenIdKeywordAnyType);
2244 if (anytype_token != nullptr) {2174 if (anytype_token != 0) {
2245 AstNode *res = ast_create_node(pc, NodeTypeParamDecl, anytype_token);2175 AstNode *res = ast_create_node(pc, NodeTypeParamDecl, anytype_token);
2246 res->data.param_decl.anytype_token = anytype_token;2176 res->data.param_decl.anytype_token = anytype_token;
2247 return res;2177 return res;
2248 }2178 }
22492179
2250 Token *dots = eat_token_if(pc, TokenIdEllipsis3);2180 TokenIndex dots = eat_token_if(pc, TokenIdEllipsis3);
2251 if (dots != nullptr) {2181 if (dots != 0) {
2252 AstNode *res = ast_create_node(pc, NodeTypeParamDecl, dots);2182 AstNode *res = ast_create_node(pc, NodeTypeParamDecl, dots);
2253 res->data.param_decl.is_var_args = true;2183 res->data.param_decl.is_var_args = true;
2254 return res;2184 return res;
...@@ -2266,8 +2196,8 @@ static AstNode *ast_parse_param_type(ParseContext *pc) {...@@ -2266,8 +2196,8 @@ static AstNode *ast_parse_param_type(ParseContext *pc) {
22662196
2267// IfPrefix <- KEYWORD_if LPAREN Expr RPAREN PtrPayload?2197// IfPrefix <- KEYWORD_if LPAREN Expr RPAREN PtrPayload?
2268static AstNode *ast_parse_if_prefix(ParseContext *pc) {2198static AstNode *ast_parse_if_prefix(ParseContext *pc) {
2269 Token *first = eat_token_if(pc, TokenIdKeywordIf);2199 TokenIndex first = eat_token_if(pc, TokenIdKeywordIf);
2270 if (first == nullptr)2200 if (first == 0)
2271 return nullptr;2201 return nullptr;
22722202
2273 expect_token(pc, TokenIdLParen);2203 expect_token(pc, TokenIdLParen);
...@@ -2279,16 +2209,16 @@ static AstNode *ast_parse_if_prefix(ParseContext *pc) {...@@ -2279,16 +2209,16 @@ static AstNode *ast_parse_if_prefix(ParseContext *pc) {
2279 AstNode *res = ast_create_node(pc, NodeTypeIfOptional, first);2209 AstNode *res = ast_create_node(pc, NodeTypeIfOptional, first);
2280 res->data.test_expr.target_node = condition;2210 res->data.test_expr.target_node = condition;
2281 if (opt_payload.unwrap(&payload)) {2211 if (opt_payload.unwrap(&payload)) {
2282 res->data.test_expr.var_symbol = token_buf(payload.payload);2212 res->data.test_expr.var_symbol = token_buf(pc, payload.payload);
2283 res->data.test_expr.var_is_ptr = payload.asterisk != nullptr;2213 res->data.test_expr.var_is_ptr = payload.asterisk != 0;
2284 }2214 }
2285 return res;2215 return res;
2286}2216}
22872217
2288// WhilePrefix <- KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr?2218// WhilePrefix <- KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr?
2289static AstNode *ast_parse_while_prefix(ParseContext *pc) {2219static AstNode *ast_parse_while_prefix(ParseContext *pc) {
2290 Token *while_token = eat_token_if(pc, TokenIdKeywordWhile);2220 TokenIndex while_token = eat_token_if(pc, TokenIdKeywordWhile);
2291 if (while_token == nullptr)2221 if (while_token == 0)
2292 return nullptr;2222 return nullptr;
22932223
2294 expect_token(pc, TokenIdLParen);2224 expect_token(pc, TokenIdLParen);
...@@ -2302,8 +2232,8 @@ static AstNode *ast_parse_while_prefix(ParseContext *pc) {...@@ -2302,8 +2232,8 @@ static AstNode *ast_parse_while_prefix(ParseContext *pc) {
2302 res->data.while_expr.condition = condition;2232 res->data.while_expr.condition = condition;
2303 res->data.while_expr.continue_expr = continue_expr;2233 res->data.while_expr.continue_expr = continue_expr;
2304 if (opt_payload.unwrap(&payload)) {2234 if (opt_payload.unwrap(&payload)) {
2305 res->data.while_expr.var_symbol = token_buf(payload.payload);2235 res->data.while_expr.var_symbol = token_buf(pc, payload.payload);
2306 res->data.while_expr.var_is_ptr = payload.asterisk != nullptr;2236 res->data.while_expr.var_is_ptr = payload.asterisk != 0;
2307 }2237 }
23082238
2309 return res;2239 return res;
...@@ -2311,8 +2241,8 @@ static AstNode *ast_parse_while_prefix(ParseContext *pc) {...@@ -2311,8 +2241,8 @@ static AstNode *ast_parse_while_prefix(ParseContext *pc) {
23112241
2312// ForPrefix <- KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload2242// ForPrefix <- KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload
2313static AstNode *ast_parse_for_prefix(ParseContext *pc) {2243static AstNode *ast_parse_for_prefix(ParseContext *pc) {
2314 Token *for_token = eat_token_if(pc, TokenIdKeywordFor);2244 TokenIndex for_token = eat_token_if(pc, TokenIdKeywordFor);
2315 if (for_token == nullptr)2245 if (for_token == 0)
2316 return nullptr;2246 return nullptr;
23172247
2318 expect_token(pc, TokenIdLParen);2248 expect_token(pc, TokenIdLParen);
...@@ -2324,31 +2254,31 @@ static AstNode *ast_parse_for_prefix(ParseContext *pc) {...@@ -2324,31 +2254,31 @@ static AstNode *ast_parse_for_prefix(ParseContext *pc) {
23242254
2325 AstNode *res = ast_create_node(pc, NodeTypeForExpr, for_token);2255 AstNode *res = ast_create_node(pc, NodeTypeForExpr, for_token);
2326 res->data.for_expr.array_expr = array_expr;2256 res->data.for_expr.array_expr = array_expr;
2327 res->data.for_expr.elem_node = token_symbol(pc, payload.payload);2257 res->data.for_expr.elem_node = token_identifier(pc, payload.payload);
2328 res->data.for_expr.elem_is_ptr = payload.asterisk != nullptr;2258 res->data.for_expr.elem_is_ptr = payload.asterisk != 0;
2329 if (payload.index != nullptr)2259 if (payload.index != 0)
2330 res->data.for_expr.index_node = token_symbol(pc, payload.index);2260 res->data.for_expr.index_node = token_identifier(pc, payload.index);
23312261
2332 return res;2262 return res;
2333}2263}
23342264
2335// Payload <- PIPE IDENTIFIER PIPE2265// Payload <- PIPE IDENTIFIER PIPE
2336static Token *ast_parse_payload(ParseContext *pc) {2266static TokenIndex ast_parse_payload(ParseContext *pc) {
2337 if (eat_token_if(pc, TokenIdBinOr) == nullptr)2267 if (eat_token_if(pc, TokenIdBinOr) == 0)
2338 return nullptr;2268 return 0;
23392269
2340 Token *res = expect_token(pc, TokenIdSymbol);2270 TokenIndex res = expect_token(pc, TokenIdIdentifier);
2341 expect_token(pc, TokenIdBinOr);2271 expect_token(pc, TokenIdBinOr);
2342 return res;2272 return res;
2343}2273}
23442274
2345// PtrPayload <- PIPE ASTERISK? IDENTIFIER PIPE2275// PtrPayload <- PIPE ASTERISK? IDENTIFIER PIPE
2346static Optional<PtrPayload> ast_parse_ptr_payload(ParseContext *pc) {2276static Optional<PtrPayload> ast_parse_ptr_payload(ParseContext *pc) {
2347 if (eat_token_if(pc, TokenIdBinOr) == nullptr)2277 if (eat_token_if(pc, TokenIdBinOr) == 0)
2348 return Optional<PtrPayload>::none();2278 return Optional<PtrPayload>::none();
23492279
2350 Token *asterisk = eat_token_if(pc, TokenIdStar);2280 TokenIndex asterisk = eat_token_if(pc, TokenIdStar);
2351 Token *payload = expect_token(pc, TokenIdSymbol);2281 TokenIndex payload = expect_token(pc, TokenIdIdentifier);
2352 expect_token(pc, TokenIdBinOr);2282 expect_token(pc, TokenIdBinOr);
23532283
2354 PtrPayload res;2284 PtrPayload res;
...@@ -2359,14 +2289,14 @@ static Optional<PtrPayload> ast_parse_ptr_payload(ParseContext *pc) {...@@ -2359,14 +2289,14 @@ static Optional<PtrPayload> ast_parse_ptr_payload(ParseContext *pc) {
23592289
2360// PtrIndexPayload <- PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE2290// PtrIndexPayload <- PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE
2361static Optional<PtrIndexPayload> ast_parse_ptr_index_payload(ParseContext *pc) {2291static 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)
2363 return Optional<PtrIndexPayload>::none();2293 return Optional<PtrIndexPayload>::none();
23642294
2365 Token *asterisk = eat_token_if(pc, TokenIdStar);2295 TokenIndex asterisk = eat_token_if(pc, TokenIdStar);
2366 Token *payload = expect_token(pc, TokenIdSymbol);2296 TokenIndex payload = expect_token(pc, TokenIdIdentifier);
2367 Token *index = nullptr;2297 TokenIndex index = 0;
2368 if (eat_token_if(pc, TokenIdComma) != nullptr)2298 if (eat_token_if(pc, TokenIdComma) != 0)
2369 index = expect_token(pc, TokenIdSymbol);2299 index = expect_token(pc, TokenIdIdentifier);
2370 expect_token(pc, TokenIdBinOr);2300 expect_token(pc, TokenIdBinOr);
23712301
2372 PtrIndexPayload res;2302 PtrIndexPayload res;
...@@ -2390,8 +2320,8 @@ static AstNode *ast_parse_switch_prong(ParseContext *pc) {...@@ -2390,8 +2320,8 @@ static AstNode *ast_parse_switch_prong(ParseContext *pc) {
2390 assert(res->type == NodeTypeSwitchProng);2320 assert(res->type == NodeTypeSwitchProng);
2391 res->data.switch_prong.expr = expr;2321 res->data.switch_prong.expr = expr;
2392 if (opt_payload.unwrap(&payload)) {2322 if (opt_payload.unwrap(&payload)) {
2393 res->data.switch_prong.var_symbol = token_symbol(pc, payload.payload);2323 res->data.switch_prong.var_symbol = token_identifier(pc, payload.payload);
2394 res->data.switch_prong.var_is_ptr = payload.asterisk != nullptr;2324 res->data.switch_prong.var_is_ptr = payload.asterisk != 0;
2395 }2325 }
23962326
2397 return res;2327 return res;
...@@ -2407,7 +2337,7 @@ static AstNode *ast_parse_switch_case(ParseContext *pc) {...@@ -2407,7 +2337,7 @@ static AstNode *ast_parse_switch_case(ParseContext *pc) {
2407 res->data.switch_prong.items.append(first);2337 res->data.switch_prong.items.append(first);
2408 res->data.switch_prong.any_items_are_range = first->type == NodeTypeSwitchRange;2338 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) {
2411 AstNode *item = ast_parse_switch_item(pc);2341 AstNode *item = ast_parse_switch_item(pc);
2412 if (item == nullptr)2342 if (item == nullptr)
2413 break;2343 break;
...@@ -2419,8 +2349,8 @@ static AstNode *ast_parse_switch_case(ParseContext *pc) {...@@ -2419,8 +2349,8 @@ static AstNode *ast_parse_switch_case(ParseContext *pc) {
2419 return res;2349 return res;
2420 }2350 }
24212351
2422 Token *else_token = eat_token_if(pc, TokenIdKeywordElse);2352 TokenIndex else_token = eat_token_if(pc, TokenIdKeywordElse);
2423 if (else_token != nullptr)2353 if (else_token != 0)
2424 return ast_create_node(pc, NodeTypeSwitchProng, else_token);2354 return ast_create_node(pc, NodeTypeSwitchProng, else_token);
24252355
2426 return nullptr;2356 return nullptr;
...@@ -2432,8 +2362,8 @@ static AstNode *ast_parse_switch_item(ParseContext *pc) {...@@ -2432,8 +2362,8 @@ static AstNode *ast_parse_switch_item(ParseContext *pc) {
2432 if (expr == nullptr)2362 if (expr == nullptr)
2433 return nullptr;2363 return nullptr;
24342364
2435 Token *dots = eat_token_if(pc, TokenIdEllipsis3);2365 TokenIndex dots = eat_token_if(pc, TokenIdEllipsis3);
2436 if (dots != nullptr) {2366 if (dots != 0) {
2437 AstNode *expr2 = ast_expect(pc, ast_parse_expr);2367 AstNode *expr2 = ast_expect(pc, ast_parse_expr);
2438 AstNode *res = ast_create_node(pc, NodeTypeSwitchRange, dots);2368 AstNode *res = ast_create_node(pc, NodeTypeSwitchRange, dots);
2439 res->data.switch_range.start = expr;2369 res->data.switch_range.start = expr;
...@@ -2478,9 +2408,9 @@ static AstNode *ast_parse_assign_op(ParseContext *pc) {...@@ -2478,9 +2408,9 @@ static AstNode *ast_parse_assign_op(ParseContext *pc) {
2478 table[TokenIdTimesEq] = BinOpTypeAssignTimes;2408 table[TokenIdTimesEq] = BinOpTypeAssignTimes;
2479 table[TokenIdTimesPercentEq] = BinOpTypeAssignTimesWrap;2409 table[TokenIdTimesPercentEq] = BinOpTypeAssignTimesWrap;
24802410
2481 BinOpType op = table[peek_token(pc)->id];2411 BinOpType op = table[pc->token_ids[pc->current_token]];
2482 if (op != BinOpTypeInvalid) {2412 if (op != BinOpTypeInvalid) {
2483 Token *op_token = eat_token(pc);2413 TokenIndex op_token = eat_token(pc);
2484 AstNode *res = ast_create_node(pc, NodeTypeBinOpExpr, op_token);2414 AstNode *res = ast_create_node(pc, NodeTypeBinOpExpr, op_token);
2485 res->data.bin_op_expr.bin_op = op;2415 res->data.bin_op_expr.bin_op = op;
2486 return res;2416 return res;
...@@ -2506,9 +2436,9 @@ static AstNode *ast_parse_compare_op(ParseContext *pc) {...@@ -2506,9 +2436,9 @@ static AstNode *ast_parse_compare_op(ParseContext *pc) {
2506 table[TokenIdCmpLessOrEq] = BinOpTypeCmpLessOrEq;2436 table[TokenIdCmpLessOrEq] = BinOpTypeCmpLessOrEq;
2507 table[TokenIdCmpGreaterOrEq] = BinOpTypeCmpGreaterOrEq;2437 table[TokenIdCmpGreaterOrEq] = BinOpTypeCmpGreaterOrEq;
25082438
2509 BinOpType op = table[peek_token(pc)->id];2439 BinOpType op = table[pc->token_ids[pc->current_token]];
2510 if (op != BinOpTypeInvalid) {2440 if (op != BinOpTypeInvalid) {
2511 Token *op_token = eat_token(pc);2441 TokenIndex op_token = eat_token(pc);
2512 AstNode *res = ast_create_node(pc, NodeTypeBinOpExpr, op_token);2442 AstNode *res = ast_create_node(pc, NodeTypeBinOpExpr, op_token);
2513 res->data.bin_op_expr.bin_op = op;2443 res->data.bin_op_expr.bin_op = op;
2514 return res;2444 return res;
...@@ -2530,20 +2460,20 @@ static AstNode *ast_parse_bitwise_op(ParseContext *pc) {...@@ -2530,20 +2460,20 @@ static AstNode *ast_parse_bitwise_op(ParseContext *pc) {
2530 table[TokenIdBinOr] = BinOpTypeBinOr;2460 table[TokenIdBinOr] = BinOpTypeBinOr;
2531 table[TokenIdKeywordOrElse] = BinOpTypeUnwrapOptional;2461 table[TokenIdKeywordOrElse] = BinOpTypeUnwrapOptional;
25322462
2533 BinOpType op = table[peek_token(pc)->id];2463 BinOpType op = table[pc->token_ids[pc->current_token]];
2534 if (op != BinOpTypeInvalid) {2464 if (op != BinOpTypeInvalid) {
2535 Token *op_token = eat_token(pc);2465 TokenIndex op_token = eat_token(pc);
2536 AstNode *res = ast_create_node(pc, NodeTypeBinOpExpr, op_token);2466 AstNode *res = ast_create_node(pc, NodeTypeBinOpExpr, op_token);
2537 res->data.bin_op_expr.bin_op = op;2467 res->data.bin_op_expr.bin_op = op;
2538 return res;2468 return res;
2539 }2469 }
25402470
2541 Token *catch_token = eat_token_if(pc, TokenIdKeywordCatch);2471 TokenIndex catch_token = eat_token_if(pc, TokenIdKeywordCatch);
2542 if (catch_token != nullptr) {2472 if (catch_token != 0) {
2543 Token *payload = ast_parse_payload(pc);2473 TokenIndex payload = ast_parse_payload(pc);
2544 AstNode *res = ast_create_node(pc, NodeTypeCatchExpr, catch_token);2474 AstNode *res = ast_create_node(pc, NodeTypeCatchExpr, catch_token);
2545 if (payload != nullptr)2475 if (payload != 0)
2546 res->data.unwrap_err_expr.symbol = token_symbol(pc, payload);2476 res->data.unwrap_err_expr.symbol = token_identifier(pc, payload);
25472477
2548 return res;2478 return res;
2549 }2479 }
...@@ -2559,9 +2489,9 @@ static AstNode *ast_parse_bit_shift_op(ParseContext *pc) {...@@ -2559,9 +2489,9 @@ static AstNode *ast_parse_bit_shift_op(ParseContext *pc) {
2559 table[TokenIdBitShiftLeft] = BinOpTypeBitShiftLeft;2489 table[TokenIdBitShiftLeft] = BinOpTypeBitShiftLeft;
2560 table[TokenIdBitShiftRight] = BinOpTypeBitShiftRight;2490 table[TokenIdBitShiftRight] = BinOpTypeBitShiftRight;
25612491
2562 BinOpType op = table[peek_token(pc)->id];2492 BinOpType op = table[pc->token_ids[pc->current_token]];
2563 if (op != BinOpTypeInvalid) {2493 if (op != BinOpTypeInvalid) {
2564 Token *op_token = eat_token(pc);2494 TokenIndex op_token = eat_token(pc);
2565 AstNode *res = ast_create_node(pc, NodeTypeBinOpExpr, op_token);2495 AstNode *res = ast_create_node(pc, NodeTypeBinOpExpr, op_token);
2566 res->data.bin_op_expr.bin_op = op;2496 res->data.bin_op_expr.bin_op = op;
2567 return res;2497 return res;
...@@ -2584,9 +2514,9 @@ static AstNode *ast_parse_addition_op(ParseContext *pc) {...@@ -2584,9 +2514,9 @@ static AstNode *ast_parse_addition_op(ParseContext *pc) {
2584 table[TokenIdPlusPercent] = BinOpTypeAddWrap;2514 table[TokenIdPlusPercent] = BinOpTypeAddWrap;
2585 table[TokenIdMinusPercent] = BinOpTypeSubWrap;2515 table[TokenIdMinusPercent] = BinOpTypeSubWrap;
25862516
2587 BinOpType op = table[peek_token(pc)->id];2517 BinOpType op = table[pc->token_ids[pc->current_token]];
2588 if (op != BinOpTypeInvalid) {2518 if (op != BinOpTypeInvalid) {
2589 Token *op_token = eat_token(pc);2519 TokenIndex op_token = eat_token(pc);
2590 AstNode *res = ast_create_node(pc, NodeTypeBinOpExpr, op_token);2520 AstNode *res = ast_create_node(pc, NodeTypeBinOpExpr, op_token);
2591 res->data.bin_op_expr.bin_op = op;2521 res->data.bin_op_expr.bin_op = op;
2592 return res;2522 return res;
...@@ -2611,9 +2541,9 @@ static AstNode *ast_parse_multiply_op(ParseContext *pc) {...@@ -2611,9 +2541,9 @@ static AstNode *ast_parse_multiply_op(ParseContext *pc) {
2611 table[TokenIdStarStar] = BinOpTypeArrayMult;2541 table[TokenIdStarStar] = BinOpTypeArrayMult;
2612 table[TokenIdTimesPercent] = BinOpTypeMultWrap;2542 table[TokenIdTimesPercent] = BinOpTypeMultWrap;
26132543
2614 BinOpType op = table[peek_token(pc)->id];2544 BinOpType op = table[pc->token_ids[pc->current_token]];
2615 if (op != BinOpTypeInvalid) {2545 if (op != BinOpTypeInvalid) {
2616 Token *op_token = eat_token(pc);2546 TokenIndex op_token = eat_token(pc);
2617 AstNode *res = ast_create_node(pc, NodeTypeBinOpExpr, op_token);2547 AstNode *res = ast_create_node(pc, NodeTypeBinOpExpr, op_token);
2618 res->data.bin_op_expr.bin_op = op;2548 res->data.bin_op_expr.bin_op = op;
2619 return res;2549 return res;
...@@ -2638,23 +2568,23 @@ static AstNode *ast_parse_prefix_op(ParseContext *pc) {...@@ -2638,23 +2568,23 @@ static AstNode *ast_parse_prefix_op(ParseContext *pc) {
2638 table[TokenIdMinusPercent] = PrefixOpNegationWrap;2568 table[TokenIdMinusPercent] = PrefixOpNegationWrap;
2639 table[TokenIdAmpersand] = PrefixOpAddrOf;2569 table[TokenIdAmpersand] = PrefixOpAddrOf;
26402570
2641 PrefixOp op = table[peek_token(pc)->id];2571 PrefixOp op = table[pc->token_ids[pc->current_token]];
2642 if (op != PrefixOpInvalid) {2572 if (op != PrefixOpInvalid) {
2643 Token *op_token = eat_token(pc);2573 TokenIndex op_token = eat_token(pc);
2644 AstNode *res = ast_create_node(pc, NodeTypePrefixOpExpr, op_token);2574 AstNode *res = ast_create_node(pc, NodeTypePrefixOpExpr, op_token);
2645 res->data.prefix_op_expr.prefix_op = op;2575 res->data.prefix_op_expr.prefix_op = op;
2646 return res;2576 return res;
2647 }2577 }
26482578
2649 Token *try_token = eat_token_if(pc, TokenIdKeywordTry);2579 TokenIndex try_token = eat_token_if(pc, TokenIdKeywordTry);
2650 if (try_token != nullptr) {2580 if (try_token != 0) {
2651 AstNode *res = ast_create_node(pc, NodeTypeReturnExpr, try_token);2581 AstNode *res = ast_create_node(pc, NodeTypeReturnExpr, try_token);
2652 res->data.return_expr.kind = ReturnKindError;2582 res->data.return_expr.kind = ReturnKindError;
2653 return res;2583 return res;
2654 }2584 }
26552585
2656 Token *await = eat_token_if(pc, TokenIdKeywordAwait);2586 TokenIndex await = eat_token_if(pc, TokenIdKeywordAwait);
2657 if (await != nullptr) {2587 if (await != 0) {
2658 AstNode *res = ast_create_node(pc, NodeTypeAwaitExpr, await);2588 AstNode *res = ast_create_node(pc, NodeTypeAwaitExpr, await);
2659 return res;2589 return res;
2660 }2590 }
...@@ -2668,16 +2598,16 @@ static AstNode *ast_parse_prefix_op(ParseContext *pc) {...@@ -2668,16 +2598,16 @@ static AstNode *ast_parse_prefix_op(ParseContext *pc) {
2668// / ArrayTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile)*2598// / ArrayTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile)*
2669// / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile)*2599// / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile)*
2670static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {2600static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {
2671 Token *questionmark = eat_token_if(pc, TokenIdQuestion);2601 TokenIndex questionmark = eat_token_if(pc, TokenIdQuestion);
2672 if (questionmark != nullptr) {2602 if (questionmark != 0) {
2673 AstNode *res = ast_create_node(pc, NodeTypePrefixOpExpr, questionmark);2603 AstNode *res = ast_create_node(pc, NodeTypePrefixOpExpr, questionmark);
2674 res->data.prefix_op_expr.prefix_op = PrefixOpOptional;2604 res->data.prefix_op_expr.prefix_op = PrefixOpOptional;
2675 return res;2605 return res;
2676 }2606 }
26772607
2678 Token *anyframe = eat_token_if(pc, TokenIdKeywordAnyFrame);2608 TokenIndex anyframe = eat_token_if(pc, TokenIdKeywordAnyFrame);
2679 if (anyframe != nullptr) {2609 if (anyframe != 0) {
2680 if (eat_token_if(pc, TokenIdArrow) != nullptr) {2610 if (eat_token_if(pc, TokenIdArrow) != 0) {
2681 AstNode *res = ast_create_node(pc, NodeTypeAnyFrameType, anyframe);2611 AstNode *res = ast_create_node(pc, NodeTypeAnyFrameType, anyframe);
2682 return res;2612 return res;
2683 }2613 }
...@@ -2685,18 +2615,18 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {...@@ -2685,18 +2615,18 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {
2685 put_back_token(pc);2615 put_back_token(pc);
2686 }2616 }
26872617
2688 Token *arr_init_lbracket = eat_token_if(pc, TokenIdLBracket);2618 TokenIndex arr_init_lbracket = eat_token_if(pc, TokenIdLBracket);
2689 if (arr_init_lbracket != nullptr) {2619 if (arr_init_lbracket != 0) {
2690 Token *underscore = eat_token_if(pc, TokenIdSymbol);2620 TokenIndex underscore = eat_token_if(pc, TokenIdIdentifier);
2691 if (underscore == nullptr) {2621 if (underscore == 0) {
2692 put_back_token(pc);2622 put_back_token(pc);
2693 } else if (!buf_eql_str(token_buf(underscore), "_")) {2623 } else if (!buf_eql_str(token_buf(pc, underscore), "_")) {
2694 put_back_token(pc);2624 put_back_token(pc);
2695 put_back_token(pc);2625 put_back_token(pc);
2696 } else {2626 } else {
2697 AstNode *sentinel = nullptr;2627 AstNode *sentinel = nullptr;
2698 Token *colon = eat_token_if(pc, TokenIdColon);2628 TokenIndex colon = eat_token_if(pc, TokenIdColon);
2699 if (colon != nullptr) {2629 if (colon != 0) {
2700 sentinel = ast_expect(pc, ast_parse_expr);2630 sentinel = ast_expect(pc, ast_parse_expr);
2701 }2631 }
2702 expect_token(pc, TokenIdRBracket);2632 expect_token(pc, TokenIdRBracket);
...@@ -2715,33 +2645,33 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {...@@ -2715,33 +2645,33 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {
2715 if (child == nullptr)2645 if (child == nullptr)
2716 child = ptr;2646 child = ptr;
2717 while (true) {2647 while (true) {
2718 Token *allowzero_token = eat_token_if(pc, TokenIdKeywordAllowZero);2648 TokenIndex allowzero_token = eat_token_if(pc, TokenIdKeywordAllowZero);
2719 if (allowzero_token != nullptr) {2649 if (allowzero_token != 0) {
2720 child->data.pointer_type.allow_zero_token = allowzero_token;2650 child->data.pointer_type.allow_zero_token = allowzero_token;
2721 continue;2651 continue;
2722 }2652 }
27232653
2724 if (eat_token_if(pc, TokenIdKeywordAlign) != nullptr) {2654 if (eat_token_if(pc, TokenIdKeywordAlign) != 0) {
2725 expect_token(pc, TokenIdLParen);2655 expect_token(pc, TokenIdLParen);
2726 AstNode *align_expr = ast_expect(pc, ast_parse_expr);2656 AstNode *align_expr = ast_expect(pc, ast_parse_expr);
2727 child->data.pointer_type.align_expr = align_expr;2657 child->data.pointer_type.align_expr = align_expr;
2728 if (eat_token_if(pc, TokenIdColon) != nullptr) {2658 if (eat_token_if(pc, TokenIdColon) != 0) {
2729 Token *bit_offset_start = expect_token(pc, TokenIdIntLiteral);2659 TokenIndex bit_offset_start = expect_token(pc, TokenIdIntLiteral);
2730 expect_token(pc, TokenIdColon);2660 expect_token(pc, TokenIdColon);
2731 Token *host_int_bytes = expect_token(pc, TokenIdIntLiteral);2661 TokenIndex host_int_bytes = expect_token(pc, TokenIdIntLiteral);
2732 child->data.pointer_type.bit_offset_start = token_bigint(bit_offset_start);2662 child->data.pointer_type.bit_offset_start = bit_offset_start;
2733 child->data.pointer_type.host_int_bytes = token_bigint(host_int_bytes);2663 child->data.pointer_type.host_int_bytes = host_int_bytes;
2734 }2664 }
2735 expect_token(pc, TokenIdRParen);2665 expect_token(pc, TokenIdRParen);
2736 continue;2666 continue;
2737 }2667 }
27382668
2739 if (eat_token_if(pc, TokenIdKeywordConst) != nullptr) {2669 if (eat_token_if(pc, TokenIdKeywordConst) != 0) {
2740 child->data.pointer_type.is_const = true;2670 child->data.pointer_type.is_const = true;
2741 continue;2671 continue;
2742 }2672 }
27432673
2744 if (eat_token_if(pc, TokenIdKeywordVolatile) != nullptr) {2674 if (eat_token_if(pc, TokenIdKeywordVolatile) != 0) {
2745 child->data.pointer_type.is_volatile = true;2675 child->data.pointer_type.is_volatile = true;
2746 continue;2676 continue;
2747 }2677 }
...@@ -2756,8 +2686,8 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {...@@ -2756,8 +2686,8 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {
2756 if (array != nullptr) {2686 if (array != nullptr) {
2757 assert(array->type == NodeTypeArrayType);2687 assert(array->type == NodeTypeArrayType);
2758 while (true) {2688 while (true) {
2759 Token *allowzero_token = eat_token_if(pc, TokenIdKeywordAllowZero);2689 TokenIndex allowzero_token = eat_token_if(pc, TokenIdKeywordAllowZero);
2760 if (allowzero_token != nullptr) {2690 if (allowzero_token != 0) {
2761 array->data.array_type.allow_zero_token = allowzero_token;2691 array->data.array_type.allow_zero_token = allowzero_token;
2762 continue;2692 continue;
2763 }2693 }
...@@ -2768,12 +2698,12 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {...@@ -2768,12 +2698,12 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {
2768 continue;2698 continue;
2769 }2699 }
27702700
2771 if (eat_token_if(pc, TokenIdKeywordConst) != nullptr) {2701 if (eat_token_if(pc, TokenIdKeywordConst) != 0) {
2772 array->data.array_type.is_const = true;2702 array->data.array_type.is_const = true;
2773 continue;2703 continue;
2774 }2704 }
27752705
2776 if (eat_token_if(pc, TokenIdKeywordVolatile) != nullptr) {2706 if (eat_token_if(pc, TokenIdKeywordVolatile) != 0) {
2777 array->data.array_type.is_volatile = true;2707 array->data.array_type.is_volatile = true;
2778 continue;2708 continue;
2779 }2709 }
...@@ -2793,14 +2723,14 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {...@@ -2793,14 +2723,14 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {
2793// / DOTASTERISK2723// / DOTASTERISK
2794// / DOTQUESTIONMARK2724// / DOTQUESTIONMARK
2795static AstNode *ast_parse_suffix_op(ParseContext *pc) {2725static AstNode *ast_parse_suffix_op(ParseContext *pc) {
2796 Token *lbracket = eat_token_if(pc, TokenIdLBracket);2726 TokenIndex lbracket = eat_token_if(pc, TokenIdLBracket);
2797 if (lbracket != nullptr) {2727 if (lbracket != 0) {
2798 AstNode *start = ast_expect(pc, ast_parse_expr);2728 AstNode *start = ast_expect(pc, ast_parse_expr);
2799 AstNode *end = nullptr;2729 AstNode *end = nullptr;
2800 if (eat_token_if(pc, TokenIdEllipsis2) != nullptr) {2730 if (eat_token_if(pc, TokenIdEllipsis2) != 0) {
2801 AstNode *sentinel = nullptr;2731 AstNode *sentinel = nullptr;
2802 end = ast_parse_expr(pc);2732 end = ast_parse_expr(pc);
2803 if (eat_token_if(pc, TokenIdColon) != nullptr) {2733 if (eat_token_if(pc, TokenIdColon) != 0) {
2804 sentinel = ast_parse_expr(pc);2734 sentinel = ast_parse_expr(pc);
2805 }2735 }
2806 expect_token(pc, TokenIdRBracket);2736 expect_token(pc, TokenIdRBracket);
...@@ -2819,18 +2749,18 @@ static AstNode *ast_parse_suffix_op(ParseContext *pc) {...@@ -2819,18 +2749,18 @@ static AstNode *ast_parse_suffix_op(ParseContext *pc) {
2819 return res;2749 return res;
2820 }2750 }
28212751
2822 Token *dot_asterisk = eat_token_if(pc, TokenIdDotStar);2752 TokenIndex dot_asterisk = eat_token_if(pc, TokenIdDotStar);
2823 if (dot_asterisk != nullptr)2753 if (dot_asterisk != 0)
2824 return ast_create_node(pc, NodeTypePtrDeref, dot_asterisk);2754 return ast_create_node(pc, NodeTypePtrDeref, dot_asterisk);
28252755
2826 Token *dot = eat_token_if(pc, TokenIdDot);2756 TokenIndex dot = eat_token_if(pc, TokenIdDot);
2827 if (dot != nullptr) {2757 if (dot != 0) {
2828 if (eat_token_if(pc, TokenIdQuestion) != nullptr)2758 if (eat_token_if(pc, TokenIdQuestion) != 0)
2829 return ast_create_node(pc, NodeTypeUnwrapOptional, dot);2759 return ast_create_node(pc, NodeTypeUnwrapOptional, dot);
28302760
2831 Token *ident = expect_token(pc, TokenIdSymbol);2761 TokenIndex ident = expect_token(pc, TokenIdIdentifier);
2832 AstNode *res = ast_create_node(pc, NodeTypeFieldAccessExpr, dot);2762 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);
2834 return res;2764 return res;
2835 }2765 }
28362766
...@@ -2839,8 +2769,8 @@ static AstNode *ast_parse_suffix_op(ParseContext *pc) {...@@ -2839,8 +2769,8 @@ static AstNode *ast_parse_suffix_op(ParseContext *pc) {
28392769
2840// FnCallArguments <- LPAREN ExprList RPAREN2770// FnCallArguments <- LPAREN ExprList RPAREN
2841static AstNode *ast_parse_fn_call_arguments(ParseContext *pc) {2771static AstNode *ast_parse_fn_call_arguments(ParseContext *pc) {
2842 Token *paren = eat_token_if(pc, TokenIdLParen);2772 TokenIndex paren = eat_token_if(pc, TokenIdLParen);
2843 if (paren == nullptr)2773 if (paren == 0)
2844 return nullptr;2774 return nullptr;
28452775
2846 ZigList<AstNode *> params = ast_parse_list(pc, TokenIdComma, ast_parse_expr);2776 ZigList<AstNode *> params = ast_parse_list(pc, TokenIdComma, ast_parse_expr);
...@@ -2854,14 +2784,14 @@ static AstNode *ast_parse_fn_call_arguments(ParseContext *pc) {...@@ -2854,14 +2784,14 @@ static AstNode *ast_parse_fn_call_arguments(ParseContext *pc) {
28542784
2855// ArrayTypeStart <- LBRACKET Expr? RBRACKET2785// ArrayTypeStart <- LBRACKET Expr? RBRACKET
2856static AstNode *ast_parse_array_type_start(ParseContext *pc) {2786static AstNode *ast_parse_array_type_start(ParseContext *pc) {
2857 Token *lbracket = eat_token_if(pc, TokenIdLBracket);2787 TokenIndex lbracket = eat_token_if(pc, TokenIdLBracket);
2858 if (lbracket == nullptr)2788 if (lbracket == 0)
2859 return nullptr;2789 return nullptr;
28602790
2861 AstNode *size = ast_parse_expr(pc);2791 AstNode *size = ast_parse_expr(pc);
2862 AstNode *sentinel = nullptr;2792 AstNode *sentinel = nullptr;
2863 Token *colon = eat_token_if(pc, TokenIdColon);2793 TokenIndex colon = eat_token_if(pc, TokenIdColon);
2864 if (colon != nullptr) {2794 if (colon != 0) {
2865 sentinel = ast_expect(pc, ast_parse_expr);2795 sentinel = ast_expect(pc, ast_parse_expr);
2866 }2796 }
2867 expect_token(pc, TokenIdRBracket);2797 expect_token(pc, TokenIdRBracket);
...@@ -2879,10 +2809,10 @@ static AstNode *ast_parse_array_type_start(ParseContext *pc) {...@@ -2879,10 +2809,10 @@ static AstNode *ast_parse_array_type_start(ParseContext *pc) {
2879static AstNode *ast_parse_ptr_type_start(ParseContext *pc) {2809static AstNode *ast_parse_ptr_type_start(ParseContext *pc) {
2880 AstNode *sentinel = nullptr;2810 AstNode *sentinel = nullptr;
28812811
2882 Token *asterisk = eat_token_if(pc, TokenIdStar);2812 TokenIndex asterisk = eat_token_if(pc, TokenIdStar);
2883 if (asterisk != nullptr) {2813 if (asterisk != 0) {
2884 Token *colon = eat_token_if(pc, TokenIdColon);2814 TokenIndex colon = eat_token_if(pc, TokenIdColon);
2885 if (colon != nullptr) {2815 if (colon != 0) {
2886 sentinel = ast_expect(pc, ast_parse_expr);2816 sentinel = ast_expect(pc, ast_parse_expr);
2887 }2817 }
2888 AstNode *res = ast_create_node(pc, NodeTypePointerType, asterisk);2818 AstNode *res = ast_create_node(pc, NodeTypePointerType, asterisk);
...@@ -2891,10 +2821,10 @@ static AstNode *ast_parse_ptr_type_start(ParseContext *pc) {...@@ -2891,10 +2821,10 @@ static AstNode *ast_parse_ptr_type_start(ParseContext *pc) {
2891 return res;2821 return res;
2892 }2822 }
28932823
2894 Token *asterisk2 = eat_token_if(pc, TokenIdStarStar);2824 TokenIndex asterisk2 = eat_token_if(pc, TokenIdStarStar);
2895 if (asterisk2 != nullptr) {2825 if (asterisk2 != 0) {
2896 Token *colon = eat_token_if(pc, TokenIdColon);2826 TokenIndex colon = eat_token_if(pc, TokenIdColon);
2897 if (colon != nullptr) {2827 if (colon != 0) {
2898 sentinel = ast_expect(pc, ast_parse_expr);2828 sentinel = ast_expect(pc, ast_parse_expr);
2899 }2829 }
2900 AstNode *res = ast_create_node(pc, NodeTypePointerType, asterisk2);2830 AstNode *res = ast_create_node(pc, NodeTypePointerType, asterisk2);
...@@ -2906,15 +2836,15 @@ static AstNode *ast_parse_ptr_type_start(ParseContext *pc) {...@@ -2906,15 +2836,15 @@ static AstNode *ast_parse_ptr_type_start(ParseContext *pc) {
2906 return res;2836 return res;
2907 }2837 }
29082838
2909 Token *lbracket = eat_token_if(pc, TokenIdLBracket);2839 TokenIndex lbracket = eat_token_if(pc, TokenIdLBracket);
2910 if (lbracket != nullptr) {2840 if (lbracket != 0) {
2911 Token *star = eat_token_if(pc, TokenIdStar);2841 TokenIndex star = eat_token_if(pc, TokenIdStar);
2912 if (star == nullptr) {2842 if (star == 0) {
2913 put_back_token(pc);2843 put_back_token(pc);
2914 } else {2844 } else {
2915 Token *c_tok = eat_token_if(pc, TokenIdSymbol);2845 TokenIndex c_tok = eat_token_if(pc, TokenIdIdentifier);
2916 if (c_tok != nullptr) {2846 if (c_tok != 0) {
2917 if (!buf_eql_str(token_buf(c_tok), "c")) {2847 if (!buf_eql_str(token_buf(pc, c_tok), "c")) {
2918 put_back_token(pc); // c symbol2848 put_back_token(pc); // c symbol
2919 } else {2849 } else {
2920 expect_token(pc, TokenIdRBracket);2850 expect_token(pc, TokenIdRBracket);
...@@ -2924,8 +2854,8 @@ static AstNode *ast_parse_ptr_type_start(ParseContext *pc) {...@@ -2924,8 +2854,8 @@ static AstNode *ast_parse_ptr_type_start(ParseContext *pc) {
2924 }2854 }
2925 }2855 }
29262856
2927 Token *colon = eat_token_if(pc, TokenIdColon);2857 TokenIndex colon = eat_token_if(pc, TokenIdColon);
2928 if (colon != nullptr) {2858 if (colon != 0) {
2929 sentinel = ast_expect(pc, ast_parse_expr);2859 sentinel = ast_expect(pc, ast_parse_expr);
2930 }2860 }
2931 expect_token(pc, TokenIdRBracket);2861 expect_token(pc, TokenIdRBracket);
...@@ -2951,9 +2881,7 @@ static AstNode *ast_parse_container_decl_auto(ParseContext *pc) {...@@ -2951,9 +2881,7 @@ static AstNode *ast_parse_container_decl_auto(ParseContext *pc) {
29512881
2952 res->data.container_decl.fields = members.fields;2882 res->data.container_decl.fields = members.fields;
2953 res->data.container_decl.decls = members.decls;2883 res->data.container_decl.decls = members.decls;
2954 if (buf_len(&members.doc_comments) != 0) {2884 res->data.container_decl.doc_comments = members.doc_comments;
2955 res->data.container_decl.doc_comments = members.doc_comments;
2956 }
2957 return res;2885 return res;
2958}2886}
29592887
...@@ -2963,8 +2891,8 @@ static AstNode *ast_parse_container_decl_auto(ParseContext *pc) {...@@ -2963,8 +2891,8 @@ static AstNode *ast_parse_container_decl_auto(ParseContext *pc) {
2963// / KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? / Expr) RPAREN)?2891// / KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? / Expr) RPAREN)?
2964// / KEYWORD_opaque2892// / KEYWORD_opaque
2965static AstNode *ast_parse_container_decl_type(ParseContext *pc) {2893static AstNode *ast_parse_container_decl_type(ParseContext *pc) {
2966 Token *first = eat_token_if(pc, TokenIdKeywordStruct);2894 TokenIndex first = eat_token_if(pc, TokenIdKeywordStruct);
2967 if (first != nullptr) {2895 if (first != 0) {
2968 AstNode *res = ast_create_node(pc, NodeTypeContainerDecl, first);2896 AstNode *res = ast_create_node(pc, NodeTypeContainerDecl, first);
2969 res->data.container_decl.init_arg_expr = nullptr;2897 res->data.container_decl.init_arg_expr = nullptr;
2970 res->data.container_decl.kind = ContainerKindStruct;2898 res->data.container_decl.kind = ContainerKindStruct;
...@@ -2972,7 +2900,7 @@ static AstNode *ast_parse_container_decl_type(ParseContext *pc) {...@@ -2972,7 +2900,7 @@ static AstNode *ast_parse_container_decl_type(ParseContext *pc) {
2972 }2900 }
29732901
2974 first = eat_token_if(pc, TokenIdKeywordOpaque);2902 first = eat_token_if(pc, TokenIdKeywordOpaque);
2975 if (first != nullptr) {2903 if (first != 0) {
2976 AstNode *res = ast_create_node(pc, NodeTypeContainerDecl, first);2904 AstNode *res = ast_create_node(pc, NodeTypeContainerDecl, first);
2977 res->data.container_decl.init_arg_expr = nullptr;2905 res->data.container_decl.init_arg_expr = nullptr;
2978 res->data.container_decl.kind = ContainerKindOpaque;2906 res->data.container_decl.kind = ContainerKindOpaque;
...@@ -2980,9 +2908,9 @@ static AstNode *ast_parse_container_decl_type(ParseContext *pc) {...@@ -2980,9 +2908,9 @@ static AstNode *ast_parse_container_decl_type(ParseContext *pc) {
2980 }2908 }
29812909
2982 first = eat_token_if(pc, TokenIdKeywordEnum);2910 first = eat_token_if(pc, TokenIdKeywordEnum);
2983 if (first != nullptr) {2911 if (first != 0) {
2984 AstNode *init_arg_expr = nullptr;2912 AstNode *init_arg_expr = nullptr;
2985 if (eat_token_if(pc, TokenIdLParen) != nullptr) {2913 if (eat_token_if(pc, TokenIdLParen) != 0) {
2986 init_arg_expr = ast_expect(pc, ast_parse_expr);2914 init_arg_expr = ast_expect(pc, ast_parse_expr);
2987 expect_token(pc, TokenIdRParen);2915 expect_token(pc, TokenIdRParen);
2988 }2916 }
...@@ -2993,13 +2921,13 @@ static AstNode *ast_parse_container_decl_type(ParseContext *pc) {...@@ -2993,13 +2921,13 @@ static AstNode *ast_parse_container_decl_type(ParseContext *pc) {
2993 }2921 }
29942922
2995 first = eat_token_if(pc, TokenIdKeywordUnion);2923 first = eat_token_if(pc, TokenIdKeywordUnion);
2996 if (first != nullptr) {2924 if (first != 0) {
2997 AstNode *init_arg_expr = nullptr;2925 AstNode *init_arg_expr = nullptr;
2998 bool auto_enum = false;2926 bool auto_enum = false;
2999 if (eat_token_if(pc, TokenIdLParen) != nullptr) {2927 if (eat_token_if(pc, TokenIdLParen) != 0) {
3000 if (eat_token_if(pc, TokenIdKeywordEnum) != nullptr) {2928 if (eat_token_if(pc, TokenIdKeywordEnum) != 0) {
3001 auto_enum = true;2929 auto_enum = true;
3002 if (eat_token_if(pc, TokenIdLParen) != nullptr) {2930 if (eat_token_if(pc, TokenIdLParen) != 0) {
3003 init_arg_expr = ast_expect(pc, ast_parse_expr);2931 init_arg_expr = ast_expect(pc, ast_parse_expr);
3004 expect_token(pc, TokenIdRParen);2932 expect_token(pc, TokenIdRParen);
3005 }2933 }
...@@ -3022,7 +2950,7 @@ static AstNode *ast_parse_container_decl_type(ParseContext *pc) {...@@ -3022,7 +2950,7 @@ static AstNode *ast_parse_container_decl_type(ParseContext *pc) {
30222950
3023// ByteAlign <- KEYWORD_align LPAREN Expr RPAREN2951// ByteAlign <- KEYWORD_align LPAREN Expr RPAREN
3024static AstNode *ast_parse_byte_align(ParseContext *pc) {2952static AstNode *ast_parse_byte_align(ParseContext *pc) {
3025 if (eat_token_if(pc, TokenIdKeywordAlign) == nullptr)2953 if (eat_token_if(pc, TokenIdKeywordAlign) == 0)
3026 return nullptr;2954 return nullptr;
30272955
3028 expect_token(pc, TokenIdLParen);2956 expect_token(pc, TokenIdLParen);
...@@ -3103,7 +3031,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont...@@ -3103,7 +3031,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
3103 case NodeTypeCharLiteral:3031 case NodeTypeCharLiteral:
3104 // none3032 // none
3105 break;3033 break;
3106 case NodeTypeSymbol:3034 case NodeTypeIdentifier:
3107 // none3035 // none
3108 break;3036 break;
3109 case NodeTypePrefixOpExpr:3037 case NodeTypePrefixOpExpr:
...@@ -3264,3 +3192,403 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont...@@ -3264,3 +3192,403 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
3264 break;3192 break;
3265 }3193 }
3266}3194}
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 @@...@@ -12,14 +12,19 @@
12#include "tokenizer.hpp"12#include "tokenizer.hpp"
13#include "errmsg.hpp"13#include "errmsg.hpp"
1414
15ATTRIBUTE_PRINTF(2, 3)15AstNode * ast_parse(Buf *buf, ZigType *owner, ErrColor err_color);
16void ast_token_error(Token *token, const char *format, ...);
17
18
19AstNode * ast_parse(Buf *buf, ZigList<Token> *tokens, ZigType *owner, ErrColor err_color);
2016
21void ast_print(AstNode *node, int indent);17void ast_print(AstNode *node, int indent);
2218
23void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *context), void *context);19void 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
25#endif30#endif
src/stage1/stage2.h+2
...@@ -112,6 +112,8 @@ enum Error {...@@ -112,6 +112,8 @@ enum Error {
112 ErrorZigIsTheCCompiler,112 ErrorZigIsTheCCompiler,
113 ErrorFileBusy,113 ErrorFileBusy,
114 ErrorLocked,114 ErrorLocked,
115 ErrorInvalidCharacter,
116 ErrorUnicodePointTooLarge,
115};117};
116118
117// ABI warning119// ABI warning
src/stage1/tokenizer.cpp+867-979
...@@ -30,18 +30,28 @@...@@ -30,18 +30,28 @@
30 case '7': \30 case '7': \
31 case '8': \31 case '8': \
32 case '9'32 case '9'
33
33#define DIGIT \34#define DIGIT \
34 '0': \35 '0': \
35 case DIGIT_NON_ZERO36 case DIGIT_NON_ZERO
3637
37#define ALPHA \38#define HEXDIGIT \
38 'a': \39 'a': \
39 case 'b': \40 case 'b': \
40 case 'c': \41 case 'c': \
41 case 'd': \42 case 'd': \
42 case 'e': \43 case 'e': \
43 case 'f': \44 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': \
45 case 'h': \55 case 'h': \
46 case 'i': \56 case 'i': \
47 case 'j': \57 case 'j': \
...@@ -49,8 +59,6 @@...@@ -49,8 +59,6 @@
49 case 'l': \59 case 'l': \
50 case 'm': \60 case 'm': \
51 case 'n': \61 case 'n': \
52 case 'o': \
53 case 'p': \
54 case 'q': \62 case 'q': \
55 case 'r': \63 case 'r': \
56 case 's': \64 case 's': \
...@@ -58,15 +66,8 @@...@@ -58,15 +66,8 @@
58 case 'u': \66 case 'u': \
59 case 'v': \67 case 'v': \
60 case 'w': \68 case 'w': \
61 case 'x': \
62 case 'y': \69 case 'y': \
63 case 'z': \70 case 'z': \
64 case 'A': \
65 case 'B': \
66 case 'C': \
67 case 'D': \
68 case 'E': \
69 case 'F': \
70 case 'G': \71 case 'G': \
71 case 'H': \72 case 'H': \
72 case 'I': \73 case 'I': \
...@@ -76,7 +77,6 @@...@@ -76,7 +77,6 @@
76 case 'M': \77 case 'M': \
77 case 'N': \78 case 'N': \
78 case 'O': \79 case 'O': \
79 case 'P': \
80 case 'Q': \80 case 'Q': \
81 case 'R': \81 case 'R': \
82 case 'S': \82 case 'S': \
...@@ -88,7 +88,46 @@...@@ -88,7 +88,46 @@
88 case 'Y': \88 case 'Y': \
89 case 'Z'89 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 \
92 ALPHA: \131 ALPHA: \
93 case DIGIT: \132 case DIGIT: \
94 case '_'133 case '_'
...@@ -157,101 +196,92 @@ static const struct ZigKeyword zig_keywords[] = {...@@ -157,101 +196,92 @@ static const struct ZigKeyword zig_keywords[] = {
157 {"while", TokenIdKeywordWhile},196 {"while", TokenIdKeywordWhile},
158};197};
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) {
161 for (size_t i = 0; i < array_length(zig_keywords); i += 1) {201 for (size_t i = 0; i < array_length(zig_keywords); i += 1) {
162 if (buf_eql_str(buf, zig_keywords[i].text)) {202 if (mem_eql_str(name_ptr, name_len, zig_keywords[i].text)) {
163 return true;203 return zig_keywords[i].token_id;
164 }204 }
165 }205 }
166 return false;206 return TokenIdIdentifier;
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 }
176}207}
177208
178enum TokenizeState {209enum TokenizeState {
179 TokenizeStateStart,210 TokenizeState_start,
180 TokenizeStateSymbol,211 TokenizeState_identifier,
181 TokenizeStateZero, // "0", which might lead to "0x"212 TokenizeState_builtin,
182 TokenizeStateNumber, // "123", "0x123"213 TokenizeState_string_literal,
183 TokenizeStateNumberNoUnderscore, // "12_", "0x12_" next char must be digit214 TokenizeState_string_literal_backslash,
184 TokenizeStateNumberDot,215 TokenizeState_multiline_string_literal_line,
185 TokenizeStateFloatFraction, // "123.456", "0x123.456"216 TokenizeState_char_literal,
186 TokenizeStateFloatFractionNoUnderscore, // "123.45_", "0x123.45_"217 TokenizeState_char_literal_backslash,
187 TokenizeStateFloatExponentUnsigned, // "123.456e", "123e", "0x123p"218 TokenizeState_char_literal_hex_escape,
188 TokenizeStateFloatExponentNumber, // "123.456e7", "123.456e+7", "123.456e-7"219 TokenizeState_char_literal_unicode_escape_saw_u,
189 TokenizeStateFloatExponentNumberNoUnderscore, // "123.456e7_", "123.456e+7_", "123.456e-7_"220 TokenizeState_char_literal_unicode_escape,
190 TokenizeStateString,221 TokenizeState_char_literal_unicode,
191 TokenizeStateStringEscape,222 TokenizeState_char_literal_end,
192 TokenizeStateStringEscapeUnicodeStart,223 TokenizeState_backslash,
193 TokenizeStateCharLiteral,224 TokenizeState_equal,
194 TokenizeStateCharLiteralEnd,225 TokenizeState_bang,
195 TokenizeStateCharLiteralUnicode,226 TokenizeState_pipe,
196 TokenizeStateSawStar,227 TokenizeState_minus,
197 TokenizeStateSawStarPercent,228 TokenizeState_minus_percent,
198 TokenizeStateSawSlash,229 TokenizeState_asterisk,
199 TokenizeStateSawSlash2,230 TokenizeState_asterisk_percent,
200 TokenizeStateSawSlash3,231 TokenizeState_slash,
201 TokenizeStateSawSlashBang,232 TokenizeState_line_comment_start,
202 TokenizeStateSawBackslash,233 TokenizeState_line_comment,
203 TokenizeStateSawPercent,234 TokenizeState_doc_comment_start,
204 TokenizeStateSawPlus,235 TokenizeState_doc_comment,
205 TokenizeStateSawPlusPercent,236 TokenizeState_container_doc_comment,
206 TokenizeStateSawDash,237 TokenizeState_zero,
207 TokenizeStateSawMinusPercent,238 TokenizeState_int_literal_dec,
208 TokenizeStateSawAmpersand,239 TokenizeState_int_literal_dec_no_underscore,
209 TokenizeStateSawCaret,240 TokenizeState_int_literal_bin,
210 TokenizeStateSawBar,241 TokenizeState_int_literal_bin_no_underscore,
211 TokenizeStateDocComment,242 TokenizeState_int_literal_oct,
212 TokenizeStateContainerDocComment,243 TokenizeState_int_literal_oct_no_underscore,
213 TokenizeStateLineComment,244 TokenizeState_int_literal_hex,
214 TokenizeStateLineString,245 TokenizeState_int_literal_hex_no_underscore,
215 TokenizeStateLineStringEnd,246 TokenizeState_num_dot_dec,
216 TokenizeStateLineStringContinue,247 TokenizeState_num_dot_hex,
217 TokenizeStateSawEq,248 TokenizeState_float_fraction_dec,
218 TokenizeStateSawBang,249 TokenizeState_float_fraction_dec_no_underscore,
219 TokenizeStateSawLessThan,250 TokenizeState_float_fraction_hex,
220 TokenizeStateSawLessThanLessThan,251 TokenizeState_float_fraction_hex_no_underscore,
221 TokenizeStateSawGreaterThan,252 TokenizeState_float_exponent_unsigned,
222 TokenizeStateSawGreaterThanGreaterThan,253 TokenizeState_float_exponent_num,
223 TokenizeStateSawDot,254 TokenizeState_float_exponent_num_no_underscore,
224 TokenizeStateSawDotDot,255 TokenizeState_ampersand,
225 TokenizeStateSawDotStar,256 TokenizeState_caret,
226 TokenizeStateSawAtSign,257 TokenizeState_percent,
227 TokenizeStateCharCode,258 TokenizeState_plus,
228 TokenizeStateError,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,
229};269};
230270
231271
232struct Tokenize {272struct Tokenize {
233 Buf *buf;273 Tokenization *out;
234 size_t pos;274 size_t pos;
235 TokenizeState state;275 TokenizeState state;
236 ZigList<Token> *tokens;276 uint32_t line;
237 int line;277 uint32_t column;
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;
247};278};
248279
249ATTRIBUTE_PRINTF(2, 3)280ATTRIBUTE_PRINTF(2, 3)
250static void tokenize_error(Tokenize *t, const char *format, ...) {281static 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;284 t->out->err_byte_offset = t->pos;
254 t->out->err_column = t->column;
255285
256 va_list ap;286 va_list ap;
257 va_start(ap, format);287 va_start(ap, format);
...@@ -259,98 +289,18 @@ static void tokenize_error(Tokenize *t, const char *format, ...) {...@@ -259,98 +289,18 @@ static void tokenize_error(Tokenize *t, const char *format, ...) {
259 va_end(ap);289 va_end(ap);
260}290}
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
276static void begin_token(Tokenize *t, TokenId id) {292static void begin_token(Tokenize *t, TokenId id) {
277 assert(!t->cur_tok);293 t->out->ids.append(id);
278 t->tokens->add_one();294 TokenLoc tok_loc;
279 Token *token = &t->tokens->last();295 tok_loc.offset = (uint32_t) t->pos;
280 token->start_line = t->line;296 tok_loc.line = t->line;
281 token->start_column = t->column;297 tok_loc.column = t->column;
282 token->start_pos = t->pos;298 t->out->locs.append(tok_loc);
283
284 set_token_id(t, token, id);
285
286 t->cur_tok = token;
287}299}
288300
289static void cancel_token(Tokenize *t) {301static void cancel_token(Tokenize *t) {
290 t->tokens->pop();302 t->out->ids.pop();
291 t->cur_tok = nullptr;303 t->out->locs.pop();
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 }
354}304}
355305
356static const char* get_escape_shorthand(uint8_t c) {306static const char* get_escape_shorthand(uint8_t c) {
...@@ -376,7 +326,15 @@ static const char* get_escape_shorthand(uint8_t c) {...@@ -376,7 +326,15 @@ static const char* get_escape_shorthand(uint8_t c) {
376 }326 }
377}327}
378328
329static void invalid_eof(Tokenize *t) {
330 return tokenize_error(t, "unexpected End-Of-File");
331}
332
379static void invalid_char_error(Tokenize *t, uint8_t c) {333static void invalid_char_error(Tokenize *t, uint8_t c) {
334 if (c == 0) {
335 return invalid_eof(t);
336 }
337
380 if (c == '\r') {338 if (c == '\r') {
381 tokenize_error(t, "invalid carriage return, only '\\n' line endings are supported");339 tokenize_error(t, "invalid carriage return, only '\\n' line endings are supported");
382 return;340 return;
...@@ -396,1139 +354,1089 @@ static void invalid_char_error(Tokenize *t, uint8_t c) {...@@ -396,1139 +354,1089 @@ static void invalid_char_error(Tokenize *t, uint8_t c) {
396 tokenize_error(t, "invalid character: '\\x%02x'", c);354 tokenize_error(t, "invalid character: '\\x%02x'", c);
397}355}
398356
399void tokenize(Buf *buf, Tokenization *out) {357void tokenize(const char *source, Tokenization *out) {
400 Tokenize t = {0};358 Tokenize t = {0};
401 t.out = out;359 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>>();361 size_t remaining_code_units;
406 out->line_offsets->append(0);362 size_t seen_escape_digits;
407363
408 // Skip the UTF-8 BOM if present364 // Skip the UTF-8 BOM if present.
409 if (buf_starts_with_mem(buf, "\xEF\xBB\xBF", 3)) {365 if (source[0] == (char)0xef &&
366 source[1] == (char)0xbb &&
367 source[2] == (char)0xbf)
368 {
410 t.pos += 3;369 t.pos += 3;
411 }370 }
412371
413 for (; t.pos < buf_len(t.buf); t.pos += 1) {372 // Invalid token takes up index 0 so that index 0 can mean "none".
414 uint8_t c = buf_ptr(t.buf)[t.pos];373 begin_token(&t, TokenIdCount);
374
375 for (;;) {
376 uint8_t c = source[t.pos];
415 switch (t.state) {377 switch (t.state) {
416 case TokenizeStateError:378 case TokenizeState_error:
417 break;379 goto eof;
418 case TokenizeStateStart:380 case TokenizeState_start:
419 switch (c) {381 switch (c) {
382 case 0:
383 goto eof;
420 case WHITESPACE:384 case WHITESPACE:
421 break;385 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;
422 case ALPHA:394 case ALPHA:
423 case '_':395 case '_':
424 t.state = TokenizeStateSymbol;396 t.state = TokenizeState_identifier;
425 begin_token(&t, TokenIdSymbol);397 begin_token(&t, TokenIdIdentifier);
426 buf_append_char(&t.cur_tok->data.str_lit.str, c);
427 break;398 break;
428 case '0':399 case '@':
429 t.state = TokenizeStateZero;400 begin_token(&t, TokenIdBuiltin);
430 begin_token(&t, TokenIdIntLiteral);401 t.state = TokenizeState_saw_at_sign;
431 t.is_trailing_underscore = false;
432 t.radix = 10;
433 bigint_init_unsigned(&t.cur_tok->data.int_lit.bigint, 0);
434 break;402 break;
435 case DIGIT_NON_ZERO:403 case '=':
436 t.state = TokenizeStateNumber;404 begin_token(&t, TokenIdEq);
437 begin_token(&t, TokenIdIntLiteral);405 t.state = TokenizeState_equal;
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));
441 break;406 break;
442 case '"':407 case '!':
443 begin_token(&t, TokenIdStringLiteral);408 begin_token(&t, TokenIdBang);
444 t.state = TokenizeStateString;409 t.state = TokenizeState_bang;
445 break;410 break;
446 case '\'':411 case '|':
447 begin_token(&t, TokenIdCharLiteral);412 begin_token(&t, TokenIdBinOr);
448 t.state = TokenizeStateCharLiteral;413 t.state = TokenizeState_pipe;
449 break;414 break;
450 case '(':415 case '(':
451 begin_token(&t, TokenIdLParen);416 begin_token(&t, TokenIdLParen);
452 end_token(&t);
453 break;417 break;
454 case ')':418 case ')':
455 begin_token(&t, TokenIdRParen);419 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);
473 break;420 break;
474 case '[':421 case '[':
475 begin_token(&t, TokenIdLBracket);422 begin_token(&t, TokenIdLBracket);
476 end_token(&t);
477 break;423 break;
478 case ']':424 case ']':
479 begin_token(&t, TokenIdRBracket);425 begin_token(&t, TokenIdRBracket);
480 end_token(&t);
481 break;426 break;
482 case ';':427 case ';':
483 begin_token(&t, TokenIdSemicolon);428 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);
485 break;435 break;
486 case ':':436 case ':':
487 begin_token(&t, TokenIdColon);437 begin_token(&t, TokenIdColon);
488 end_token(&t);
489 break;438 break;
490 case '#':439 case '%':
491 begin_token(&t, TokenIdNumberSign);440 begin_token(&t, TokenIdPercent);
492 end_token(&t);441 t.state = TokenizeState_percent;
493 break;442 break;
494 case '*':443 case '*':
495 begin_token(&t, TokenIdStar);444 begin_token(&t, TokenIdStar);
496 t.state = TokenizeStateSawStar;445 t.state = TokenizeState_asterisk;
497 break;446 break;
498 case '/':447 case '+':
499 begin_token(&t, TokenIdSlash);448 begin_token(&t, TokenIdPlus);
500 t.state = TokenizeStateSawSlash;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;
501 break;462 break;
502 case '\\':463 case '\\':
503 begin_token(&t, TokenIdMultilineStringLiteral);464 begin_token(&t, TokenIdMultilineStringLiteralLine);
504 t.state = TokenizeStateSawBackslash;465 t.state = TokenizeState_backslash;
505 break;466 break;
506 case '%':467 case '{':
507 begin_token(&t, TokenIdPercent);468 begin_token(&t, TokenIdLBrace);
508 t.state = TokenizeStateSawPercent;
509 break;469 break;
510 case '+':470 case '}':
511 begin_token(&t, TokenIdPlus);471 begin_token(&t, TokenIdRBrace);
512 t.state = TokenizeStateSawPlus;
513 break;472 break;
514 case '~':473 case '~':
515 begin_token(&t, TokenIdTilde);474 begin_token(&t, TokenIdTilde);
516 end_token(&t);
517 break;475 break;
518 case '@':476 case '.':
519 begin_token(&t, TokenIdAtSign);477 begin_token(&t, TokenIdDot);
520 t.state = TokenizeStateSawAtSign;478 t.state = TokenizeState_period;
521 break;479 break;
522 case '-':480 case '-':
523 begin_token(&t, TokenIdDash);481 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;
525 break;487 break;
526 case '&':488 case '&':
527 begin_token(&t, TokenIdAmpersand);489 begin_token(&t, TokenIdAmpersand);
528 t.state = TokenizeStateSawAmpersand;490 t.state = TokenizeState_ampersand;
529 break;491 break;
530 case '^':492 case '0':
531 begin_token(&t, TokenIdBinXor);493 t.state = TokenizeState_zero;
532 t.state = TokenizeStateSawCaret;494 begin_token(&t, TokenIdIntLiteral);
533 break;
534 case '|':
535 begin_token(&t, TokenIdBinOr);
536 t.state = TokenizeStateSawBar;
537 break;495 break;
538 case '=':496 case DIGIT_NON_ZERO:
539 begin_token(&t, TokenIdEq);497 t.state = TokenizeState_int_literal_dec;
540 t.state = TokenizeStateSawEq;498 begin_token(&t, TokenIdIntLiteral);
541 break;499 break;
542 case '!':500 default:
543 begin_token(&t, TokenIdBang);501 invalid_char_error(&t, c);
544 t.state = TokenizeStateSawBang;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;
545 break;512 break;
546 case '<':513 case IDENTIFIER_CHAR:
547 begin_token(&t, TokenIdCmpLessThan);514 t.state = TokenizeState_builtin;
548 t.state = TokenizeStateSawLessThan;
549 break;515 break;
550 case '>':516 default:
551 begin_token(&t, TokenIdCmpGreaterThan);517 invalid_char_error(&t, c);
552 t.state = TokenizeStateSawGreaterThan;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");
553 break;526 break;
554 case '.':527 case '=':
555 begin_token(&t, TokenIdDot);528 t.out->ids.last() = TokenIdBitAndEq;
556 t.state = TokenizeStateSawDot;529 t.state = TokenizeState_start;
557 break;530 break;
558 default:531 default:
559 invalid_char_error(&t, c);532 t.state = TokenizeState_start;
533 continue;
560 }534 }
561 break;535 break;
562 case TokenizeStateSawDot:536 case TokenizeState_asterisk:
563 switch (c) {537 switch (c) {
564 case '.':538 case 0:
565 t.state = TokenizeStateSawDotDot;539 goto eof;
566 set_token_id(&t, t.cur_tok, TokenIdEllipsis2);540 case '=':
541 t.out->ids.last() = TokenIdTimesEq;
542 t.state = TokenizeState_start;
567 break;543 break;
568 case '*':544 case '*':
569 t.state = TokenizeStateSawDotStar;545 t.out->ids.last() = TokenIdStarStar;
570 set_token_id(&t, t.cur_tok, TokenIdDotStar);546 t.state = TokenizeState_start;
547 break;
548 case '%':
549 t.state = TokenizeState_asterisk_percent;
571 break;550 break;
572 default:551 default:
573 t.pos -= 1;552 t.state = TokenizeState_start;
574 end_token(&t);
575 t.state = TokenizeStateStart;
576 continue;553 continue;
577 }554 }
578 break;555 break;
579 case TokenizeStateSawDotDot:556 case TokenizeState_asterisk_percent:
580 switch (c) {557 switch (c) {
581 case '.':558 case 0:
582 t.state = TokenizeStateStart;559 t.out->ids.last() = TokenIdTimesPercent;
583 set_token_id(&t, t.cur_tok, TokenIdEllipsis3);560 goto eof;
584 end_token(&t);561 case '=':
562 t.out->ids.last() = TokenIdTimesPercentEq;
563 t.state = TokenizeState_start;
585 break;564 break;
586 default:565 default:
587 t.pos -= 1;566 t.out->ids.last() = TokenIdTimesPercent;
588 end_token(&t);567 t.state = TokenizeState_start;
589 t.state = TokenizeStateStart;
590 continue;568 continue;
591 }569 }
592 break;570 break;
593 case TokenizeStateSawDotStar:571 case TokenizeState_percent:
594 switch (c) {572 switch (c) {
595 case '*':573 case 0:
596 tokenize_error(&t, "`.*` can't be followed by `*`. Are you missing a space?");574 goto eof;
575 case '=':
576 t.out->ids.last() = TokenIdModEq;
577 t.state = TokenizeState_start;
597 break;578 break;
598 default:579 default:
599 t.pos -= 1;580 t.state = TokenizeState_start;
600 end_token(&t);
601 t.state = TokenizeStateStart;
602 continue;581 continue;
603 }582 }
604 break;583 break;
605 case TokenizeStateSawGreaterThan:584 case TokenizeState_plus:
606 switch (c) {585 switch (c) {
586 case 0:
587 goto eof;
607 case '=':588 case '=':
608 set_token_id(&t, t.cur_tok, TokenIdCmpGreaterOrEq);589 t.out->ids.last() = TokenIdPlusEq;
609 end_token(&t);590 t.state = TokenizeState_start;
610 t.state = TokenizeStateStart;
611 break;591 break;
612 case '>':592 case '+':
613 set_token_id(&t, t.cur_tok, TokenIdBitShiftRight);593 t.out->ids.last() = TokenIdPlusPlus;
614 t.state = TokenizeStateSawGreaterThanGreaterThan;594 t.state = TokenizeState_start;
595 break;
596 case '%':
597 t.state = TokenizeState_plus_percent;
615 break;598 break;
616 default:599 default:
617 t.pos -= 1;600 t.state = TokenizeState_start;
618 end_token(&t);
619 t.state = TokenizeStateStart;
620 continue;601 continue;
621 }602 }
622 break;603 break;
623 case TokenizeStateSawGreaterThanGreaterThan:604 case TokenizeState_plus_percent:
624 switch (c) {605 switch (c) {
606 case 0:
607 t.out->ids.last() = TokenIdPlusPercent;
608 goto eof;
625 case '=':609 case '=':
626 set_token_id(&t, t.cur_tok, TokenIdBitShiftRightEq);610 t.out->ids.last() = TokenIdPlusPercentEq;
627 end_token(&t);611 t.state = TokenizeState_start;
628 t.state = TokenizeStateStart;
629 break;612 break;
630 default:613 default:
631 t.pos -= 1;614 t.out->ids.last() = TokenIdPlusPercent;
632 end_token(&t);615 t.state = TokenizeState_start;
633 t.state = TokenizeStateStart;
634 continue;616 continue;
635 }617 }
636 break;618 break;
637 case TokenizeStateSawLessThan:619 case TokenizeState_caret:
638 switch (c) {620 switch (c) {
621 case 0:
622 goto eof;
639 case '=':623 case '=':
640 set_token_id(&t, t.cur_tok, TokenIdCmpLessOrEq);624 t.out->ids.last() = TokenIdBitXorEq;
641 end_token(&t);625 t.state = TokenizeState_start;
642 t.state = TokenizeStateStart;
643 break;626 break;
644 case '<':627 default:
645 set_token_id(&t, t.cur_tok, TokenIdBitShiftLeft);628 t.state = TokenizeState_start;
646 t.state = TokenizeStateSawLessThanLessThan;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:
647 break;657 break;
648 default:658 default:
649 t.pos -= 1;659 t.state = TokenizeState_start;
650 end_token(&t);
651 t.state = TokenizeStateStart;
652 continue;660 continue;
653 }661 }
654 break;662 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:
656 switch (c) {784 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;
657 case '=':836 case '=':
658 set_token_id(&t, t.cur_tok, TokenIdBitShiftLeftEq);837 t.out->ids.last() = TokenIdCmpNotEq;
659 end_token(&t);838 t.state = TokenizeState_start;
660 t.state = TokenizeStateStart;
661 break;839 break;
662 default:840 default:
663 t.pos -= 1;841 t.state = TokenizeState_start;
664 end_token(&t);
665 t.state = TokenizeStateStart;
666 continue;842 continue;
667 }843 }
668 break;844 break;
669 case TokenizeStateSawBang:845 case TokenizeState_pipe:
670 switch (c) {846 switch (c) {
847 case 0:
848 goto eof;
671 case '=':849 case '=':
672 set_token_id(&t, t.cur_tok, TokenIdCmpNotEq);850 t.out->ids.last() = TokenIdBitOrEq;
673 end_token(&t);851 t.state = TokenizeState_start;
674 t.state = TokenizeStateStart;852 break;
853 case '|':
854 t.out->ids.last() = TokenIdBarBar;
855 t.state = TokenizeState_start;
675 break;856 break;
676 default:857 default:
677 t.pos -= 1;858 t.state = TokenizeState_start;
678 end_token(&t);
679 t.state = TokenizeStateStart;
680 continue;859 continue;
681 }860 }
682 break;861 break;
683 case TokenizeStateSawEq:862 case TokenizeState_equal:
684 switch (c) {863 switch (c) {
864 case 0:
865 goto eof;
685 case '=':866 case '=':
686 set_token_id(&t, t.cur_tok, TokenIdCmpEq);867 t.out->ids.last() = TokenIdCmpEq;
687 end_token(&t);868 t.state = TokenizeState_start;
688 t.state = TokenizeStateStart;
689 break;869 break;
690 case '>':870 case '>':
691 set_token_id(&t, t.cur_tok, TokenIdFatArrow);871 t.out->ids.last() = TokenIdFatArrow;
692 end_token(&t);872 t.state = TokenizeState_start;
693 t.state = TokenizeStateStart;
694 break;873 break;
695 default:874 default:
696 t.pos -= 1;875 t.state = TokenizeState_start;
697 end_token(&t);
698 t.state = TokenizeStateStart;
699 continue;876 continue;
700 }877 }
701 break;878 break;
702 case TokenizeStateSawStar:879 case TokenizeState_minus:
703 switch (c) {880 switch (c) {
704 case '=':881 case 0:
705 set_token_id(&t, t.cur_tok, TokenIdTimesEq);882 goto eof;
706 end_token(&t);883 case '>':
707 t.state = TokenizeStateStart;884 t.out->ids.last() = TokenIdArrow;
885 t.state = TokenizeState_start;
708 break;886 break;
709 case '*':887 case '=':
710 set_token_id(&t, t.cur_tok, TokenIdStarStar);888 t.out->ids.last() = TokenIdMinusEq;
711 end_token(&t);889 t.state = TokenizeState_start;
712 t.state = TokenizeStateStart;
713 break;890 break;
714 case '%':891 case '%':
715 set_token_id(&t, t.cur_tok, TokenIdTimesPercent);892 t.state = TokenizeState_minus_percent;
716 t.state = TokenizeStateSawStarPercent;
717 break;893 break;
718 default:894 default:
719 t.pos -= 1;895 t.state = TokenizeState_start;
720 end_token(&t);
721 t.state = TokenizeStateStart;
722 continue;896 continue;
723 }897 }
724 break;898 break;
725 case TokenizeStateSawStarPercent:899 case TokenizeState_minus_percent:
726 switch (c) {900 switch (c) {
901 case 0:
902 t.out->ids.last() = TokenIdMinusPercent;
903 goto eof;
727 case '=':904 case '=':
728 set_token_id(&t, t.cur_tok, TokenIdTimesPercentEq);905 t.out->ids.last() = TokenIdMinusPercentEq;
729 end_token(&t);906 t.state = TokenizeState_start;
730 t.state = TokenizeStateStart;
731 break;907 break;
732 default:908 default:
733 t.pos -= 1;909 t.out->ids.last() = TokenIdMinusPercent;
734 end_token(&t);910 t.state = TokenizeState_start;
735 t.state = TokenizeStateStart;
736 continue;911 continue;
737 }912 }
738 break;913 break;
739 case TokenizeStateSawPercent:914 case TokenizeState_angle_bracket_left:
740 switch (c) {915 switch (c) {
916 case 0:
917 goto eof;
741 case '=':918 case '=':
742 set_token_id(&t, t.cur_tok, TokenIdModEq);919 t.out->ids.last() = TokenIdCmpLessOrEq;
743 end_token(&t);920 t.state = TokenizeState_start;
744 t.state = TokenizeStateStart;
745 break;921 break;
746 case '.':922 case '<':
747 set_token_id(&t, t.cur_tok, TokenIdPercentDot);923 t.state = TokenizeState_angle_bracket_angle_bracket_left;
748 end_token(&t);
749 t.state = TokenizeStateStart;
750 break;924 break;
751 default:925 default:
752 t.pos -= 1;926 t.state = TokenizeState_start;
753 end_token(&t);
754 t.state = TokenizeStateStart;
755 continue;927 continue;
756 }928 }
757 break;929 break;
758 case TokenizeStateSawPlus:930 case TokenizeState_angle_bracket_angle_bracket_left:
759 switch (c) {931 switch (c) {
932 case 0:
933 t.out->ids.last() = TokenIdBitShiftLeft;
934 goto eof;
760 case '=':935 case '=':
761 set_token_id(&t, t.cur_tok, TokenIdPlusEq);936 t.out->ids.last() = TokenIdBitShiftLeftEq;
762 end_token(&t);937 t.state = TokenizeState_start;
763 t.state = TokenizeStateStart;
764 break;938 break;
765 case '+':939 default:
766 set_token_id(&t, t.cur_tok, TokenIdPlusPlus);940 t.out->ids.last() = TokenIdBitShiftLeft;
767 end_token(&t);941 t.state = TokenizeState_start;
768 t.state = TokenizeStateStart;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;
769 break;952 break;
770 case '%':953 case '>':
771 set_token_id(&t, t.cur_tok, TokenIdPlusPercent);954 t.state = TokenizeState_angle_bracket_angle_bracket_right;
772 t.state = TokenizeStateSawPlusPercent;
773 break;955 break;
774 default:956 default:
775 t.pos -= 1;957 t.state = TokenizeState_start;
776 end_token(&t);
777 t.state = TokenizeStateStart;
778 continue;958 continue;
779 }959 }
780 break;960 break;
781 case TokenizeStateSawPlusPercent:961 case TokenizeState_angle_bracket_angle_bracket_right:
782 switch (c) {962 switch (c) {
963 case 0:
964 t.out->ids.last() = TokenIdBitShiftRight;
965 goto eof;
783 case '=':966 case '=':
784 set_token_id(&t, t.cur_tok, TokenIdPlusPercentEq);967 t.out->ids.last() = TokenIdBitShiftRightEq;
785 end_token(&t);968 t.state = TokenizeState_start;
786 t.state = TokenizeStateStart;
787 break;969 break;
788 default:970 default:
789 t.pos -= 1;971 t.out->ids.last() = TokenIdBitShiftRight;
790 end_token(&t);972 t.state = TokenizeState_start;
791 t.state = TokenizeStateStart;
792 continue;973 continue;
793 }974 }
794 break;975 break;
795 case TokenizeStateSawAmpersand:976 case TokenizeState_period:
796 switch (c) {977 switch (c) {
797 case '&':978 case 0:
798 tokenize_error(&t, "`&&` is invalid. Note that `and` is boolean AND");979 goto eof;
980 case '.':
981 t.state = TokenizeState_period_2;
799 break;982 break;
800 case '=':983 case '*':
801 set_token_id(&t, t.cur_tok, TokenIdBitAndEq);984 t.state = TokenizeState_period_asterisk;
802 end_token(&t);
803 t.state = TokenizeStateStart;
804 break;985 break;
805 default:986 default:
806 t.pos -= 1;987 t.state = TokenizeState_start;
807 end_token(&t);
808 t.state = TokenizeStateStart;
809 continue;988 continue;
810 }989 }
811 break;990 break;
812 case TokenizeStateSawCaret:991 case TokenizeState_period_2:
813 switch (c) {992 switch (c) {
814 case '=':993 case 0:
815 set_token_id(&t, t.cur_tok, TokenIdBitXorEq);994 t.out->ids.last() = TokenIdEllipsis2;
816 end_token(&t);995 goto eof;
817 t.state = TokenizeStateStart;996 case '.':
997 t.out->ids.last() = TokenIdEllipsis3;
998 t.state = TokenizeState_start;
818 break;999 break;
819 default:1000 default:
820 t.pos -= 1;1001 t.out->ids.last() = TokenIdEllipsis2;
821 end_token(&t);1002 t.state = TokenizeState_start;
822 t.state = TokenizeStateStart;
823 continue;1003 continue;
824 }1004 }
825 break;1005 break;
826 case TokenizeStateSawBar:1006 case TokenizeState_period_asterisk:
827 switch (c) {1007 switch (c) {
828 case '=':1008 case 0:
829 set_token_id(&t, t.cur_tok, TokenIdBitOrEq);1009 t.out->ids.last() = TokenIdDotStar;
830 end_token(&t);1010 goto eof;
831 t.state = TokenizeStateStart;1011 case '*':
832 break;1012 tokenize_error(&t, "`.*` cannot be followed by `*`. Are you missing a space?");
833 case '|':
834 set_token_id(&t, t.cur_tok, TokenIdBarBar);
835 end_token(&t);
836 t.state = TokenizeStateStart;
837 break;1013 break;
838 default:1014 default:
839 t.pos -= 1;1015 t.out->ids.last() = TokenIdDotStar;
840 end_token(&t);1016 t.state = TokenizeState_start;
841 t.state = TokenizeStateStart;
842 continue;1017 continue;
843 }1018 }
844 break;1019 break;
845 case TokenizeStateSawSlash:1020 case TokenizeState_slash:
846 switch (c) {1021 switch (c) {
1022 case 0:
1023 goto eof;
847 case '/':1024 case '/':
848 t.state = TokenizeStateSawSlash2;1025 t.state = TokenizeState_line_comment_start;
849 break;1026 break;
850 case '=':1027 case '=':
851 set_token_id(&t, t.cur_tok, TokenIdDivEq);1028 t.out->ids.last() = TokenIdDivEq;
852 end_token(&t);1029 t.state = TokenizeState_start;
853 t.state = TokenizeStateStart;
854 break;1030 break;
855 default:1031 default:
856 t.pos -= 1;1032 t.state = TokenizeState_start;
857 end_token(&t);
858 t.state = TokenizeStateStart;
859 continue;1033 continue;
860 }1034 }
861 break;1035 break;
862 case TokenizeStateSawSlash2:1036 case TokenizeState_line_comment_start:
863 switch (c) {1037 switch (c) {
1038 case 0:
1039 goto eof;
864 case '/':1040 case '/':
865 t.state = TokenizeStateSawSlash3;1041 t.state = TokenizeState_doc_comment_start;
866 break;1042 break;
867 case '!':1043 case '!':
868 t.state = TokenizeStateSawSlashBang;1044 t.out->ids.last() = TokenIdContainerDocComment;
1045 t.state = TokenizeState_container_doc_comment;
869 break;1046 break;
870 case '\n':1047 case '\n':
871 cancel_token(&t);1048 cancel_token(&t);
872 t.state = TokenizeStateStart;1049 t.state = TokenizeState_start;
873 break;1050 break;
874 default:1051 default:
875 cancel_token(&t);1052 cancel_token(&t);
876 t.state = TokenizeStateLineComment;1053 t.state = TokenizeState_line_comment;
877 break;1054 break;
878 }1055 }
879 break;1056 break;
880 case TokenizeStateSawSlash3:1057 case TokenizeState_doc_comment_start:
881 switch (c) {1058 switch (c) {
1059 case 0:
1060 t.out->ids.last() = TokenIdDocComment;
1061 goto eof;
882 case '/':1062 case '/':
883 cancel_token(&t);1063 cancel_token(&t);
884 t.state = TokenizeStateLineComment;1064 t.state = TokenizeState_line_comment;
885 break;1065 break;
886 case '\n':1066 case '\n':
887 set_token_id(&t, t.cur_tok, TokenIdDocComment);1067 t.out->ids.last() = TokenIdDocComment;
888 end_token(&t);1068 t.state = TokenizeState_start;
889 t.state = TokenizeStateStart;
890 break;1069 break;
891 default:1070 default:
892 set_token_id(&t, t.cur_tok, TokenIdDocComment);1071 t.out->ids.last() = TokenIdDocComment;
893 t.state = TokenizeStateDocComment;1072 t.state = TokenizeState_doc_comment;
894 break;1073 break;
895 }1074 }
896 break;1075 break;
897 case TokenizeStateSawSlashBang:1076 case TokenizeState_line_comment:
898 switch (c) {1077 switch (c) {
1078 case 0:
1079 goto eof;
899 case '\n':1080 case '\n':
900 set_token_id(&t, t.cur_tok, TokenIdContainerDocComment);1081 t.state = TokenizeState_start;
901 end_token(&t);
902 t.state = TokenizeStateStart;
903 break;1082 break;
904 default:1083 default:
905 set_token_id(&t, t.cur_tok, TokenIdContainerDocComment);
906 t.state = TokenizeStateContainerDocComment;
907 break;1084 break;
908 }1085 }
909 break;1086 break;
910 case TokenizeStateSawBackslash:1087 case TokenizeState_doc_comment:
1088 case TokenizeState_container_doc_comment:
911 switch (c) {1089 switch (c) {
912 case '\\':1090 case 0:
913 t.state = TokenizeStateLineString;1091 goto eof;
1092 case '\n':
1093 t.state = TokenizeState_start;
914 break;1094 break;
915 default:1095 default:
916 invalid_char_error(&t, c);1096 // do nothing
917 break;1097 break;
918 }1098 }
919 break;1099 break;
920 case TokenizeStateLineString:1100 case TokenizeState_zero:
921 switch (c) {1101 switch (c) {
922 case '\n':1102 case 0:
923 t.state = TokenizeStateLineStringEnd;1103 goto eof;
1104 case 'b':
1105 t.state = TokenizeState_int_literal_bin_no_underscore;
924 break;1106 break;
925 default:1107 case 'o':
926 buf_append_char(&t.cur_tok->data.str_lit.str, c);1108 t.state = TokenizeState_int_literal_oct_no_underscore;
927 break;1109 break;
928 }1110 case 'x':
929 break;1111 t.state = TokenizeState_int_literal_hex_no_underscore;
930 case TokenizeStateLineStringEnd:
931 switch (c) {
932 case WHITESPACE:
933 break;1112 break;
934 case '\\':1113 case DIGIT:
935 t.state = TokenizeStateLineStringContinue;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);
936 break;1123 break;
937 default:1124 default:
938 t.pos -= 1;1125 t.state = TokenizeState_start;
939 end_token(&t);
940 t.state = TokenizeStateStart;
941 continue;1126 continue;
942 }1127 }
943 break;1128 break;
944 case TokenizeStateLineStringContinue:1129 case TokenizeState_int_literal_bin_no_underscore:
945 switch (c) {1130 switch (c) {
946 case '\\':1131 case '0':
947 t.state = TokenizeStateLineString;1132 case '1':
948 buf_append_char(&t.cur_tok->data.str_lit.str, '\n');1133 t.state = TokenizeState_int_literal_bin;
949 break;1134 break;
950 default:1135 default:
951 invalid_char_error(&t, c);1136 invalid_char_error(&t, c);
952 break;
953 }1137 }
954 break;1138 break;
955 case TokenizeStateLineComment:1139 case TokenizeState_int_literal_bin:
956 switch (c) {1140 switch (c) {
957 case '\n':1141 case 0:
958 t.state = TokenizeStateStart;1142 goto eof;
1143 case '_':
1144 t.state = TokenizeState_int_literal_bin_no_underscore;
959 break;1145 break;
960 default:1146 case '0':
961 // do nothing1147 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);
962 break;1159 break;
1160 default:
1161 t.state = TokenizeState_start;
1162 continue;
963 }1163 }
964 break;1164 break;
965 case TokenizeStateDocComment:1165 case TokenizeState_int_literal_oct_no_underscore:
966 switch (c) {1166 switch (c) {
967 case '\n':1167 case '0':
968 end_token(&t);1168 case '1':
969 t.state = TokenizeStateStart;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;
970 break;1176 break;
971 default:1177 default:
972 // do nothing1178 invalid_char_error(&t, c);
973 break;1179 break;
974 }1180 }
975 break;1181 break;
976 case TokenizeStateContainerDocComment:1182 case TokenizeState_int_literal_oct:
977 switch (c) {1183 switch (c) {
978 case '\n':1184 case 0:
979 end_token(&t);1185 goto eof;
980 t.state = TokenizeStateStart;1186 case '_':
1187 t.state = TokenizeState_int_literal_oct_no_underscore;
981 break;1188 break;
982 default:1189 case '0':
983 // do nothing1190 case '1':
1191 case '2':
1192 case '3':
1193 case '4':
1194 case '5':
1195 case '6':
1196 case '7':
984 break;1197 break;
985 }1198 case ALPHA:
986 break;1199 case '8':
987 case TokenizeStateSawAtSign:1200 case '9':
988 switch (c) {1201 invalid_char_error(&t, c);
989 case '"':
990 set_token_id(&t, t.cur_tok, TokenIdSymbol);
991 t.state = TokenizeStateString;
992 break;1202 break;
993 default:1203 default:
994 t.pos -= 1;1204 t.state = TokenizeState_start;
995 end_token(&t);
996 t.state = TokenizeStateStart;
997 continue;1205 continue;
998 }1206 }
999 break;1207 break;
1000 case TokenizeStateSymbol:1208 case TokenizeState_int_literal_dec_no_underscore:
1001 switch (c) {1209 switch (c) {
1002 case SYMBOL_CHAR:1210 case DIGIT:
1003 buf_append_char(&t.cur_tok->data.str_lit.str, c);1211 t.state = TokenizeState_int_literal_dec;
1004 break;1212 break;
1005 default:1213 default:
1006 t.pos -= 1;1214 invalid_char_error(&t, c);
1007 end_token(&t);1215 break;
1008 t.state = TokenizeStateStart;
1009 continue;
1010 }1216 }
1011 break;1217 break;
1012 case TokenizeStateString:1218 case TokenizeState_int_literal_dec:
1013 switch (c) {1219 switch (c) {
1014 case '"':1220 case 0:
1015 end_token(&t);1221 goto eof;
1016 t.state = TokenizeStateStart;1222 case '_':
1223 t.state = TokenizeState_int_literal_dec_no_underscore;
1017 break;1224 break;
1018 case '\n':1225 case '.':
1019 tokenize_error(&t, "newline not allowed in string literal");1226 t.state = TokenizeState_num_dot_dec;
1227 t.out->ids.last() = TokenIdFloatLiteral;
1020 break;1228 break;
1021 case '\\':1229 case 'e':
1022 t.state = TokenizeStateStringEscape;1230 case 'E':
1231 t.state = TokenizeState_float_exponent_unsigned;
1232 t.out->ids.last() = TokenIdFloatLiteral;
1023 break;1233 break;
1024 default:1234 case DIGIT:
1025 buf_append_char(&t.cur_tok->data.str_lit.str, c);1235 break;
1236 case ALPHA_EXCEPT_E:
1237 invalid_char_error(&t, c);
1026 break;1238 break;
1239 default:
1240 t.state = TokenizeState_start;
1241 continue;
1027 }1242 }
1028 break;1243 break;
1029 case TokenizeStateStringEscape:1244 case TokenizeState_int_literal_hex_no_underscore:
1030 switch (c) {1245 switch (c) {
1031 case 'x':1246 case HEXDIGIT:
1032 t.state = TokenizeStateCharCode;1247 t.state = TokenizeState_int_literal_hex;
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');
1043 break;1248 break;
1044 case 'r':1249 default:
1045 handle_string_escape(&t, '\r');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;
1046 break;1259 break;
1047 case '\\':1260 case '.':
1048 handle_string_escape(&t, '\\');1261 t.state = TokenizeState_num_dot_hex;
1262 t.out->ids.last() = TokenIdFloatLiteral;
1049 break;1263 break;
1050 case 't':1264 case 'p':
1051 handle_string_escape(&t, '\t');1265 case 'P':
1266 t.state = TokenizeState_float_exponent_unsigned;
1267 t.out->ids.last() = TokenIdFloatLiteral;
1052 break;1268 break;
1053 case '\'':1269 case HEXDIGIT:
1054 handle_string_escape(&t, '\'');
1055 break;1270 break;
1056 case '"':1271 case ALPHA_EXCEPT_HEX_AND_P:
1057 handle_string_escape(&t, '\"');1272 invalid_char_error(&t, c);
1058 break;1273 break;
1059 default:1274 default:
1060 invalid_char_error(&t, c);1275 t.state = TokenizeState_start;
1276 continue;
1061 }1277 }
1062 break;1278 break;
1063 case TokenizeStateStringEscapeUnicodeStart:1279 case TokenizeState_num_dot_dec:
1064 switch (c) {1280 switch (c) {
1065 case '{':1281 case 0:
1066 t.state = TokenizeStateCharCode;1282 goto eof;
1067 t.radix = 16;1283 case '.':
1068 t.char_code = 0;1284 t.out->ids.last() = TokenIdIntLiteral;
1069 t.char_code_index = 0;1285 t.pos -= 1;
1070 t.unicode = true;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;
1071 break;1295 break;
1072 default:1296 default:
1073 invalid_char_error(&t, c);1297 invalid_char_error(&t, c);
1298 break;
1074 }1299 }
1075 break;1300 break;
1076 case TokenizeStateCharCode:1301 case TokenizeState_num_dot_hex:
1077 {1302 switch (c) {
1078 if (t.unicode && c == '}') {1303 case 0:
1079 if (t.char_code_index == 0) {1304 goto eof;
1080 tokenize_error(&t, "empty unicode escape sequence");1305 case '.':
1081 break;1306 t.out->ids.last() = TokenIdIntLiteral;
1082 }1307 t.pos -= 1;
1083 if (t.char_code > 0x10ffff) {1308 t.column -= 1;
1084 tokenize_error(&t, "unicode value out of range: %x", t.char_code);1309 t.state = TokenizeState_start;
1085 break;1310 continue;
1086 }1311 case 'p':
1087 if (t.cur_tok->id == TokenIdCharLiteral) {1312 case 'P':
1088 t.cur_tok->data.char_lit.c = t.char_code;1313 t.state = TokenizeState_float_exponent_unsigned;
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 }
1117 break;1314 break;
1118 }1315 case HEXDIGIT:
11191316 t.out->ids.last() = TokenIdFloatLiteral;
1120 uint32_t digit_value = get_digit_value(c);1317 t.state = TokenizeState_float_fraction_hex;
1121 if (digit_value >= t.radix) {1318 break;
1122 tokenize_error(&t, "invalid digit: '%c'", c);1319 default:
1320 invalid_char_error(&t, c);
1123 break;1321 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;
1162 }1322 }
1163 break;1323 break;
1164 case TokenizeStateCharLiteralEnd:1324 case TokenizeState_float_fraction_dec_no_underscore:
1165 switch (c) {1325 switch (c) {
1166 case '\'':1326 case DIGIT:
1167 end_token(&t);1327 t.state = TokenizeState_float_fraction_dec;
1168 t.state = TokenizeStateStart;
1169 break;1328 break;
1170 default:1329 default:
1171 invalid_char_error(&t, c);1330 invalid_char_error(&t, c);
1172 }1331 }
1173 break;1332 break;
1174 case TokenizeStateCharLiteralUnicode:1333 case TokenizeState_float_fraction_dec:
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:
1186 switch (c) {1334 switch (c) {
1187 case 'b':1335 case 0:
1188 t.radix = 2;1336 goto eof;
1189 t.state = TokenizeStateNumberNoUnderscore;1337 case '_':
1338 t.state = TokenizeState_float_fraction_dec_no_underscore;
1190 break;1339 break;
1191 case 'o':1340 case 'e':
1192 t.radix = 8;1341 case 'E':
1193 t.state = TokenizeStateNumberNoUnderscore;1342 t.state = TokenizeState_float_exponent_unsigned;
1194 break;1343 break;
1195 case 'x':1344 case DIGIT:
1196 t.radix = 16;1345 break;
1197 t.state = TokenizeStateNumberNoUnderscore;1346 case ALPHA_EXCEPT_E:
1347 invalid_char_error(&t, c);
1198 break;1348 break;
1199 default:1349 default:
1200 // reinterpret as normal number1350 t.state = TokenizeState_start;
1201 t.pos -= 1;
1202 t.state = TokenizeStateNumber;
1203 continue;1351 continue;
1204 }1352 }
1205 break;1353 break;
1206 case TokenizeStateNumberNoUnderscore:1354 case TokenizeState_float_fraction_hex_no_underscore:
1207 if (c == '_') {1355 switch (c) {
1208 invalid_char_error(&t, c);1356 case HEXDIGIT:
1209 break;1357 t.state = TokenizeState_float_fraction_hex;
1210 } else if (get_digit_value(c) < t.radix) {1358 break;
1211 t.is_trailing_underscore = false;1359 default:
1212 t.state = TokenizeStateNumber;1360 invalid_char_error(&t, c);
1213 }1361 }
1214 ZIG_FALLTHROUGH;1362 break;
1215 case TokenizeStateNumber:1363 case TokenizeState_float_fraction_hex:
1216 {1364 switch (c) {
1217 if (c == '_') {1365 case 0:
1218 t.is_trailing_underscore = true;1366 goto eof;
1219 t.state = TokenizeStateNumberNoUnderscore;1367 case '_':
1368 t.state = TokenizeState_float_fraction_hex_no_underscore;
1220 break;1369 break;
1221 }1370 case 'p':
1222 if (c == '.') {1371 case 'P':
1223 if (t.is_trailing_underscore) {1372 t.state = TokenizeState_float_exponent_unsigned;
1224 invalid_char_error(&t, c);
1225 break;
1226 }
1227 t.state = TokenizeStateNumberDot;
1228 break;1373 break;
1229 }1374 case HEXDIGIT:
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);
1242 break;1375 break;
1243 }1376 case ALPHA_EXCEPT_HEX_AND_P:
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) {
1281 invalid_char_error(&t, c);1377 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
1311 break;1378 break;
1312 }1379 default:
1313 uint32_t digit_value = get_digit_value(c);1380 t.state = TokenizeState_start;
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;
1326 continue;1381 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
1331 }1382 }
1332 break;1383 break;
1333 case TokenizeStateFloatExponentUnsigned:1384 case TokenizeState_float_exponent_unsigned:
1334 switch (c) {1385 switch (c) {
1335 case '+':1386 case '+':
1336 t.state = TokenizeStateFloatExponentNumberNoUnderscore;
1337 break;
1338 case '-':1387 case '-':
1339 t.state = TokenizeStateFloatExponentNumberNoUnderscore;1388 t.state = TokenizeState_float_exponent_num_no_underscore;
1340 break;1389 break;
1341 default:1390 default:
1342 // reinterpret as normal exponent number1391 // Reinterpret as a normal exponent number.
1343 t.pos -= 1;1392 t.state = TokenizeState_float_exponent_num_no_underscore;
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;
1376 continue;1393 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
1381 }1394 }
1382 break;1395 break;
1383 case TokenizeStateSawDash:1396 case TokenizeState_float_exponent_num_no_underscore:
1384 switch (c) {1397 switch (c) {
1385 case '>':1398 case DIGIT:
1386 set_token_id(&t, t.cur_tok, TokenIdArrow);1399 t.state = TokenizeState_float_exponent_num;
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 break;1400 break;
1399 default:1401 default:
1400 t.pos -= 1;1402 invalid_char_error(&t, c);
1401 end_token(&t);
1402 t.state = TokenizeStateStart;
1403 continue;
1404 }1403 }
1405 break;1404 break;
1406 case TokenizeStateSawMinusPercent:1405 case TokenizeState_float_exponent_num:
1407 switch (c) {1406 switch (c) {
1408 case '=':1407 case 0:
1409 set_token_id(&t, t.cur_tok, TokenIdMinusPercentEq);1408 goto eof;
1410 end_token(&t);1409 case '_':
1411 t.state = TokenizeStateStart;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);
1412 break;1416 break;
1413 default:1417 default:
1414 t.pos -= 1;1418 t.state = TokenizeState_start;
1415 end_token(&t);
1416 t.state = TokenizeStateStart;
1417 continue;1419 continue;
1418 }1420 }
1419 break;1421 break;
1420 }1422 }
1423 t.pos += 1;
1421 if (c == '\n') {1424 if (c == '\n') {
1422 out->line_offsets->append(t.pos + 1);
1423 t.line += 1;1425 t.line += 1;
1424 t.column = 0;1426 t.column = 0;
1425 } else {1427 } else {
1426 t.column += 1;1428 t.column += 1;
1427 }1429 }
1428 }1430 }
1429 // EOF1431eof:;
1430 switch (t.state) {1432
1431 case TokenizeStateStart:1433 begin_token(&t, TokenIdEof);
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 }
1525}1434}
15261435
1527const char * token_name(TokenId id) {1436const char * token_name(TokenId id) {
1528 switch (id) {1437 switch (id) {
1529 case TokenIdAmpersand: return "&";1438 case TokenIdAmpersand: return "&";
1530 case TokenIdArrow: return "->";1439 case TokenIdArrow: return "->";
1531 case TokenIdAtSign: return "@";
1532 case TokenIdBang: return "!";1440 case TokenIdBang: return "!";
1533 case TokenIdBarBar: return "||";1441 case TokenIdBarBar: return "||";
1534 case TokenIdBinOr: return "|";1442 case TokenIdBinOr: return "|";
...@@ -1622,9 +1530,7 @@ const char * token_name(TokenId id) {...@@ -1622,9 +1530,7 @@ const char * token_name(TokenId id) {
1622 case TokenIdMinusPercent: return "-%";1530 case TokenIdMinusPercent: return "-%";
1623 case TokenIdMinusPercentEq: return "-%=";1531 case TokenIdMinusPercentEq: return "-%=";
1624 case TokenIdModEq: return "%=";1532 case TokenIdModEq: return "%=";
1625 case TokenIdNumberSign: return "#";
1626 case TokenIdPercent: return "%";1533 case TokenIdPercent: return "%";
1627 case TokenIdPercentDot: return "%.";
1628 case TokenIdPlus: return "+";1534 case TokenIdPlus: return "+";
1629 case TokenIdPlusEq: return "+=";1535 case TokenIdPlusEq: return "+=";
1630 case TokenIdPlusPercent: return "+%";1536 case TokenIdPlusPercent: return "+%";
...@@ -1638,33 +1544,15 @@ const char * token_name(TokenId id) {...@@ -1638,33 +1544,15 @@ const char * token_name(TokenId id) {
1638 case TokenIdStar: return "*";1544 case TokenIdStar: return "*";
1639 case TokenIdStarStar: return "**";1545 case TokenIdStarStar: return "**";
1640 case TokenIdStringLiteral: return "StringLiteral";1546 case TokenIdStringLiteral: return "StringLiteral";
1641 case TokenIdMultilineStringLiteral: return "MultilineStringLiteral";1547 case TokenIdMultilineStringLiteralLine: return "MultilineStringLiteralLine";
1642 case TokenIdSymbol: return "Symbol";1548 case TokenIdIdentifier: return "Identifier";
1643 case TokenIdTilde: return "~";1549 case TokenIdTilde: return "~";
1644 case TokenIdTimesEq: return "*=";1550 case TokenIdTimesEq: return "*=";
1645 case TokenIdTimesPercent: return "*%";1551 case TokenIdTimesPercent: return "*%";
1646 case TokenIdTimesPercentEq: return "*%=";1552 case TokenIdTimesPercentEq: return "*%=";
1553 case TokenIdBuiltin: return "Builtin";
1647 case TokenIdCount:1554 case TokenIdCount:
1648 zig_unreachable();1555 zig_unreachable();
1649 }1556 }
1650 return "(invalid token)";1557 return "(invalid token)";
1651}1558}
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 @@...@@ -12,10 +12,9 @@
12#include "bigint.hpp"12#include "bigint.hpp"
13#include "bigfloat.hpp"13#include "bigfloat.hpp"
1414
15enum TokenId {15enum TokenId : uint8_t {
16 TokenIdAmpersand,16 TokenIdAmpersand,
17 TokenIdArrow,17 TokenIdArrow,
18 TokenIdAtSign,
19 TokenIdBang,18 TokenIdBang,
20 TokenIdBarBar,19 TokenIdBarBar,
21 TokenIdBinOr,20 TokenIdBinOr,
...@@ -27,6 +26,7 @@ enum TokenId {...@@ -27,6 +26,7 @@ enum TokenId {
27 TokenIdBitShiftRight,26 TokenIdBitShiftRight,
28 TokenIdBitShiftRightEq,27 TokenIdBitShiftRightEq,
29 TokenIdBitXorEq,28 TokenIdBitXorEq,
29 TokenIdBuiltin,
30 TokenIdCharLiteral,30 TokenIdCharLiteral,
31 TokenIdCmpEq,31 TokenIdCmpEq,
32 TokenIdCmpGreaterOrEq,32 TokenIdCmpGreaterOrEq,
...@@ -109,9 +109,7 @@ enum TokenId {...@@ -109,9 +109,7 @@ enum TokenId {
109 TokenIdMinusPercent,109 TokenIdMinusPercent,
110 TokenIdMinusPercentEq,110 TokenIdMinusPercentEq,
111 TokenIdModEq,111 TokenIdModEq,
112 TokenIdNumberSign,
113 TokenIdPercent,112 TokenIdPercent,
114 TokenIdPercentDot,
115 TokenIdPlus,113 TokenIdPlus,
116 TokenIdPlusEq,114 TokenIdPlusEq,
117 TokenIdPlusPercent,115 TokenIdPlusPercent,
...@@ -125,75 +123,35 @@ enum TokenId {...@@ -125,75 +123,35 @@ enum TokenId {
125 TokenIdStar,123 TokenIdStar,
126 TokenIdStarStar,124 TokenIdStarStar,
127 TokenIdStringLiteral,125 TokenIdStringLiteral,
128 TokenIdMultilineStringLiteral,126 TokenIdMultilineStringLiteralLine,
129 TokenIdSymbol,127 TokenIdIdentifier,
130 TokenIdTilde,128 TokenIdTilde,
131 TokenIdTimesEq,129 TokenIdTimesEq,
132 TokenIdTimesPercent,130 TokenIdTimesPercent,
133 TokenIdTimesPercentEq,131 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 {133 TokenIdCount,
153 uint32_t c;
154};134};
155135
156struct Token {136typedef uint32_t TokenIndex;
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;
169137
170 // TokenIdStringLiteral, TokenIdMultilineStringLiteral or TokenIdSymbol138struct TokenLoc {
171 TokenStrLit str_lit;139 uint32_t offset;
172140 uint32_t line;
173 // TokenIdCharLiteral141 uint32_t column;
174 TokenCharLit char_lit;
175 } data;
176};142};
177// work around conflicting name Token which is also found in libclang
178typedef Token ZigToken;
179143
180struct Tokenization {144struct Tokenization {
181 ZigList<Token> *tokens;145 ZigList<TokenId> ids;
182 ZigList<size_t> *line_offsets;146 ZigList<TokenLoc> locs;
183147
184 // if an error occurred148 // if an error occurred
185 Buf *err;149 Buf *err;
186 size_t err_line;150 uint32_t err_byte_offset;
187 size_t err_column;
188};151};
189152
190void tokenize(Buf *buf, Tokenization *out_tokenization);153void tokenize(const char *source, Tokenization *out_tokenization);
191
192void print_tokens(Buf *buf, ZigList<Token> *tokens);
193154
194const char * token_name(TokenId id);155const char * token_name(TokenId id);
195156
196bool valid_symbol_starter(uint8_t c);
197bool is_zig_keyword(Buf *buf);
198
199#endif157#endif
test/behavior/misc.zig+8-7
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1const std = @import("std");1const std = @import("std");
2const expect = std.testing.expect;2const expect = std.testing.expect;
3const expectEqualSlices = std.testing.expectEqualSlices;3const expectEqualSlices = std.testing.expectEqualSlices;
4const expectEqualStrings = std.testing.expectEqualStrings;
4const mem = std.mem;5const mem = std.mem;
5const builtin = @import("builtin");6const builtin = @import("builtin");
67
...@@ -147,13 +148,13 @@ test "array mult operator" {...@@ -147,13 +148,13 @@ test "array mult operator" {
147}148}
148149
149test "string escapes" {150test "string escapes" {
150 try expect(mem.eql(u8, "\"", "\x22"));151 try expectEqualStrings("\"", "\x22");
151 try expect(mem.eql(u8, "\'", "\x27"));152 try expectEqualStrings("\'", "\x27");
152 try expect(mem.eql(u8, "\n", "\x0a"));153 try expectEqualStrings("\n", "\x0a");
153 try expect(mem.eql(u8, "\r", "\x0d"));154 try expectEqualStrings("\r", "\x0d");
154 try expect(mem.eql(u8, "\t", "\x09"));155 try expectEqualStrings("\t", "\x09");
155 try expect(mem.eql(u8, "\\", "\x5c"));156 try expectEqualStrings("\\", "\x5c");
156 try expect(mem.eql(u8, "\u{1234}\u{069}\u{1}", "\xe1\x88\xb4\x69\x01"));157 try expectEqualStrings("\u{1234}\u{069}\u{1}", "\xe1\x88\xb4\x69\x01");
157}158}
158159
159test "multiline string" {160test "multiline string" {
test/compile_errors.zig+4-4
...@@ -34,9 +34,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -34,9 +34,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
34 \\ const c: *S = &.{};34 \\ const c: *S = &.{};
35 \\}35 \\}
36 , &[_][]const u8{36 , &[_][]const u8{
37 "mp.zig:2:31: error: expected type '[][]const u8', found '*const struct:2:31'",37 "tmp.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'",38 "tmp.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'",39 "tmp.zig:9:21: error: expected type '*S', found '*const struct:9:21'",
40 });40 });
4141
42 cases.add("@Type() union payload is undefined",42 cases.add("@Type() union payload is undefined",
...@@ -8416,6 +8416,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8416,6 +8416,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8416 \\ var sequence = "repeat".*** 10;8416 \\ var sequence = "repeat".*** 10;
8417 \\}8417 \\}
8418 , &[_][]const u8{8418 , &[_][]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?",
8420 });8420 });
8421}8421}