authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-22 15:31:35-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-22 15:31:35-07:00
log272fe1c54c76ddab2dbecc2b302a651929c4b994
tree3781d8cd1831d9d4aad16721df8ab898a3fdb64e
parentb09a0cd0727055217742cb178822521733078c27

implicit casts rewrite the AST


6 files changed, 630 insertions(+), 369 deletions(-)

src/all_types.hpp+19-27
...@@ -22,7 +22,6 @@ struct FnTableEntry;...@@ -22,7 +22,6 @@ struct FnTableEntry;
22struct BlockContext;22struct BlockContext;
23struct TypeTableEntry;23struct TypeTableEntry;
24struct VariableTableEntry;24struct VariableTableEntry;
25struct Cast;
26struct BuiltinFnEntry;25struct BuiltinFnEntry;
27struct LabelTableEntry;26struct LabelTableEntry;
28struct TypeStructField;27struct TypeStructField;
...@@ -41,15 +40,6 @@ enum CodeGenBuildType {...@@ -41,15 +40,6 @@ enum CodeGenBuildType {
41 CodeGenBuildTypeRelease,40 CodeGenBuildTypeRelease,
42};41};
4342
44enum CastOp {
45 CastOpNothing,
46 CastOpPtrToInt,
47 CastOpIntWidenOrShorten,
48 CastOpToUnknownSizeArray,
49 CastOpMaybeWrap,
50 CastOpPointerReinterpret,
51};
52
53struct ConstEnumValue {43struct ConstEnumValue {
54 uint64_t tag;44 uint64_t tag;
55 ConstExprValue *payload;45 ConstExprValue *payload;
...@@ -69,29 +59,15 @@ struct ConstExprValue {...@@ -69,29 +59,15 @@ struct ConstExprValue {
69 } data;59 } data;
70};60};
7161
72struct Cast {
73 CastOp op;
74 // if op is CastOpArrayToString, this will be a pointer to
75 // the string struct on the stack
76 LLVMValueRef ptr;
77 TypeTableEntry *after_type;
78 AstNode *source_node;
79 ConstExprValue const_val;
80};
81
82struct Expr {62struct Expr {
83 TypeTableEntry *type_entry;63 TypeTableEntry *type_entry;
84 TypeTableEntry *resolved_type;
85 // the context in which this expression is evaluated.64 // the context in which this expression is evaluated.
86 // for blocks, this points to the containing scope, not the block's own scope for its children.65 // for blocks, this points to the containing scope, not the block's own scope for its children.
87 BlockContext *block_context;66 BlockContext *block_context;
8867
89 // may be null for no cast
90 Cast implicit_cast; // happens first
91 Cast implicit_maybe_cast; // happens second
92
93 LLVMValueRef const_llvm_val;68 LLVMValueRef const_llvm_val;
94 ConstExprValue const_val;69 ConstExprValue const_val;
70 bool has_global_const;
95};71};
9672
97struct StructValExprCodeGen {73struct StructValExprCodeGen {
...@@ -305,6 +281,16 @@ struct AstNodeBinOpExpr {...@@ -305,6 +281,16 @@ struct AstNodeBinOpExpr {
305 Expr resolved_expr;281 Expr resolved_expr;
306};282};
307283
284enum CastOp {
285 CastOpNoCast, // signifies the function call expression is not a cast
286 CastOpNoop, // fn call expr is a cast, but does nothing
287 CastOpPtrToInt,
288 CastOpIntWidenOrShorten,
289 CastOpToUnknownSizeArray,
290 CastOpMaybeWrap,
291 CastOpPointerReinterpret,
292};
293
308struct AstNodeFnCallExpr {294struct AstNodeFnCallExpr {
309 AstNode *fn_ref_expr;295 AstNode *fn_ref_expr;
310 ZigList<AstNode *> params;296 ZigList<AstNode *> params;
...@@ -313,8 +299,11 @@ struct AstNodeFnCallExpr {...@@ -313,8 +299,11 @@ struct AstNodeFnCallExpr {
313 // populated by semantic analyzer:299 // populated by semantic analyzer:
314 BuiltinFnEntry *builtin_fn;300 BuiltinFnEntry *builtin_fn;
315 Expr resolved_expr;301 Expr resolved_expr;
316 Cast cast;
317 FnTableEntry *fn_entry;302 FnTableEntry *fn_entry;
303 CastOp cast_op;
304 // if cast_op is CastOpArrayToString, this will be a pointer to
305 // the string struct on the stack
306 LLVMValueRef tmp_ptr;
318};307};
319308
320struct AstNodeArrayAccessExpr {309struct AstNodeArrayAccessExpr {
...@@ -610,6 +599,8 @@ struct AstNodeSymbolExpr {...@@ -610,6 +599,8 @@ struct AstNodeSymbolExpr {
610 Expr resolved_expr;599 Expr resolved_expr;
611 VariableTableEntry *variable;600 VariableTableEntry *variable;
612 FnTableEntry *fn_entry;601 FnTableEntry *fn_entry;
602 // set this to instead of analyzing the node, pretend it's a type entry and it's this one.
603 TypeTableEntry *override_type_entry;
613};604};
614605
615struct AstNodeBoolLiteral {606struct AstNodeBoolLiteral {
...@@ -644,6 +635,7 @@ struct AstNode {...@@ -644,6 +635,7 @@ struct AstNode {
644 int column;635 int column;
645 uint32_t create_index; // for determinism purposes636 uint32_t create_index; // for determinism purposes
646 ImportTableEntry *owner;637 ImportTableEntry *owner;
638 AstNode **parent_field; // for AST rewriting
647 union {639 union {
648 AstNodeRoot root;640 AstNodeRoot root;
649 AstNodeRootExportDecl root_export_decl;641 AstNodeRootExportDecl root_export_decl;
...@@ -997,7 +989,7 @@ struct BlockContext {...@@ -997,7 +989,7 @@ struct BlockContext {
997 BlockContext *parent; // null when this is the root989 BlockContext *parent; // null when this is the root
998 HashMap<Buf *, VariableTableEntry *, buf_hash, buf_eql_buf> variable_table;990 HashMap<Buf *, VariableTableEntry *, buf_hash, buf_eql_buf> variable_table;
999 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> type_table;991 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> type_table;
1000 ZigList<Cast *> cast_expr_alloca_list;992 ZigList<AstNode *> cast_alloca_list;
1001 ZigList<StructValExprCodeGen *> struct_val_expr_alloca_list;993 ZigList<StructValExprCodeGen *> struct_val_expr_alloca_list;
1002 ZigList<VariableTableEntry *> variable_list;994 ZigList<VariableTableEntry *> variable_list;
1003 AstNode *parent_loop_node;995 AstNode *parent_loop_node;
src/analyze.cpp+290-215
...@@ -17,6 +17,8 @@ static VariableTableEntry *analyze_variable_declaration(CodeGen *g, ImportTableE...@@ -17,6 +17,8 @@ static VariableTableEntry *analyze_variable_declaration(CodeGen *g, ImportTableE
17 BlockContext *context, TypeTableEntry *expected_type, AstNode *node);17 BlockContext *context, TypeTableEntry *expected_type, AstNode *node);
18static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *struct_type);18static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *struct_type);
19static TypeTableEntry *unwrapped_node_type(AstNode *node);19static TypeTableEntry *unwrapped_node_type(AstNode *node);
20static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
21 AstNode *node);
2022
21static AstNode *first_executing_node(AstNode *node) {23static AstNode *first_executing_node(AstNode *node) {
22 switch (node->type) {24 switch (node->type) {
...@@ -369,6 +371,9 @@ static TypeTableEntry *get_unknown_size_array_type(CodeGen *g, TypeTableEntry *c...@@ -369,6 +371,9 @@ static TypeTableEntry *get_unknown_size_array_type(CodeGen *g, TypeTableEntry *c
369// and returns invalid type. Otherwise, returns the type of the constant expression value.371// and returns invalid type. Otherwise, returns the type of the constant expression value.
370// Must be called after analyze_expression on the same node.372// Must be called after analyze_expression on the same node.
371static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node) {373static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node) {
374 if (node->type == NodeTypeSymbol && node->data.symbol_expr.override_type_entry) {
375 return node->data.symbol_expr.override_type_entry;
376 }
372 Expr *expr = get_resolved_expr(node);377 Expr *expr = get_resolved_expr(node);
373 assert(expr->type_entry);378 assert(expr->type_entry);
374 if (expr->type_entry->id == TypeTableEntryIdInvalid) {379 if (expr->type_entry->id == TypeTableEntryIdInvalid) {
...@@ -393,8 +398,9 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node) {...@@ -393,8 +398,9 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node) {
393static TypeTableEntry *analyze_type_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,398static TypeTableEntry *analyze_type_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
394 AstNode *node)399 AstNode *node)
395{400{
396 analyze_expression(g, import, context, nullptr, node);401 AstNode **node_ptr = node->parent_field;
397 return resolve_type(g, node);402 analyze_expression(g, import, context, nullptr, *node_ptr);
403 return resolve_type(g, *node_ptr);
398}404}
399405
400static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_table_entry,406static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_table_entry,
...@@ -1044,12 +1050,43 @@ static TypeTableEntry *get_return_type(BlockContext *context) {...@@ -1044,12 +1050,43 @@ static TypeTableEntry *get_return_type(BlockContext *context) {
1044 return unwrapped_node_type(return_type_node);1050 return unwrapped_node_type(return_type_node);
1045}1051}
10461052
1053static bool type_has_codegen_value(TypeTableEntryId id) {
1054 switch (id) {
1055 case TypeTableEntryIdInvalid:
1056 case TypeTableEntryIdMetaType:
1057 case TypeTableEntryIdVoid:
1058 case TypeTableEntryIdUnreachable:
1059 case TypeTableEntryIdNumLitFloat:
1060 case TypeTableEntryIdNumLitInt:
1061 return false;
1062
1063 case TypeTableEntryIdBool:
1064 case TypeTableEntryIdInt:
1065 case TypeTableEntryIdFloat:
1066 case TypeTableEntryIdPointer:
1067 case TypeTableEntryIdArray:
1068 case TypeTableEntryIdStruct:
1069 case TypeTableEntryIdMaybe:
1070 case TypeTableEntryIdError:
1071 case TypeTableEntryIdEnum:
1072 case TypeTableEntryIdFn:
1073 return true;
1074 }
1075 zig_unreachable();
1076}
1077
1078static void add_global_const_expr(CodeGen *g, Expr *expr) {
1079 if (expr->const_val.ok && type_has_codegen_value(expr->type_entry->id) && !expr->has_global_const) {
1080 g->global_const_list.append(expr);
1081 expr->has_global_const = true;
1082 }
1083}
1084
1047static bool num_lit_fits_in_other_type(CodeGen *g, AstNode *literal_node, TypeTableEntry *other_type) {1085static bool num_lit_fits_in_other_type(CodeGen *g, AstNode *literal_node, TypeTableEntry *other_type) {
1048 Expr *expr = get_resolved_expr(literal_node);1086 Expr *expr = get_resolved_expr(literal_node);
1049 ConstExprValue *const_val = &expr->const_val;1087 ConstExprValue *const_val = &expr->const_val;
1050 assert(const_val->ok);1088 assert(const_val->ok);
1051 if (other_type->id == TypeTableEntryIdFloat) {1089 if (other_type->id == TypeTableEntryIdFloat) {
1052 expr->resolved_type = other_type;
1053 return true;1090 return true;
1054 } else if (other_type->id == TypeTableEntryIdInt &&1091 } else if (other_type->id == TypeTableEntryIdInt &&
1055 const_val->data.x_bignum.kind == BigNumKindInt)1092 const_val->data.x_bignum.kind == BigNumKindInt)
...@@ -1057,7 +1094,6 @@ static bool num_lit_fits_in_other_type(CodeGen *g, AstNode *literal_node, TypeTa...@@ -1057,7 +1094,6 @@ static bool num_lit_fits_in_other_type(CodeGen *g, AstNode *literal_node, TypeTa
1057 if (bignum_fits_in_bits(&const_val->data.x_bignum, other_type->size_in_bits,1094 if (bignum_fits_in_bits(&const_val->data.x_bignum, other_type->size_in_bits,
1058 other_type->data.integral.is_signed))1095 other_type->data.integral.is_signed))
1059 {1096 {
1060 expr->resolved_type = other_type;
1061 return true;1097 return true;
1062 }1098 }
1063 } else if (other_type->id == TypeTableEntryIdNumLitFloat ||1099 } else if (other_type->id == TypeTableEntryIdNumLitFloat ||
...@@ -1145,39 +1181,74 @@ static TypeTableEntry *determine_peer_type_compatibility(CodeGen *g, AstNode *pa...@@ -1145,39 +1181,74 @@ static TypeTableEntry *determine_peer_type_compatibility(CodeGen *g, AstNode *pa
1145 return prev_type;1181 return prev_type;
1146}1182}
11471183
1148static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *context, AstNode *node,1184static bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *actual_type) {
1149 TypeTableEntry *expected_type, TypeTableEntry *actual_type)
1150{
1151 if (expected_type == nullptr)
1152 return actual_type; // anything will do
1153 if (expected_type == actual_type)1185 if (expected_type == actual_type)
1154 return expected_type; // match1186 return true;
1155 if (expected_type->id == TypeTableEntryIdInvalid || actual_type->id == TypeTableEntryIdInvalid)1187
1156 return expected_type; // already complained1188 // pointer const
1157 if (actual_type->id == TypeTableEntryIdUnreachable)1189 if (expected_type->id == TypeTableEntryIdPointer &&
1158 return actual_type; // sorry toots; gotta run. good luck with that expected type.1190 actual_type->id == TypeTableEntryIdPointer &&
1191 (!actual_type->data.pointer.is_const || expected_type->data.pointer.is_const))
1192 {
1193 return types_match_const_cast_only(expected_type->data.pointer.child_type,
1194 actual_type->data.pointer.child_type);
1195 }
11591196
1197 // unknown size array const
1198 if (expected_type->id == TypeTableEntryIdStruct &&
1199 actual_type->id == TypeTableEntryIdStruct &&
1200 expected_type->data.structure.is_unknown_size_array &&
1201 actual_type->data.structure.is_unknown_size_array &&
1202 (!actual_type->data.structure.fields[0].type_entry->data.pointer.is_const ||
1203 expected_type->data.structure.fields[0].type_entry->data.pointer.is_const))
1204 {
1205 return types_match_const_cast_only(
1206 expected_type->data.structure.fields[0].type_entry->data.pointer.child_type,
1207 actual_type->data.structure.fields[0].type_entry->data.pointer.child_type);
1208 }
1209
1210 // maybe
1160 if (expected_type->id == TypeTableEntryIdMaybe &&1211 if (expected_type->id == TypeTableEntryIdMaybe &&
1161 actual_type->id == TypeTableEntryIdMaybe)1212 actual_type->id == TypeTableEntryIdMaybe)
1162 {1213 {
1163 TypeTableEntry *expected_child = expected_type->data.maybe.child_type;1214 return types_match_const_cast_only(
1164 TypeTableEntry *actual_child = actual_type->data.maybe.child_type;1215 expected_type->data.maybe.child_type,
1165 return resolve_type_compatibility(g, context, node, expected_child, actual_child);1216 actual_type->data.maybe.child_type);
1217 }
1218
1219 // error
1220 if (expected_type->id == TypeTableEntryIdError &&
1221 actual_type->id == TypeTableEntryIdError)
1222 {
1223 return types_match_const_cast_only(
1224 expected_type->data.error.child_type,
1225 actual_type->data.error.child_type);
1226 }
1227
1228 // fn
1229 if (expected_type->id == TypeTableEntryIdFn &&
1230 actual_type->id == TypeTableEntryIdFn)
1231 {
1232 zig_panic("TODO types_match_const_cast_only for fns");
1233 }
1234
1235
1236 return false;
1237}
1238
1239static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_type,
1240 TypeTableEntry *actual_type, AstNode *literal_node, bool *reported_err)
1241{
1242 if (types_match_const_cast_only(expected_type, actual_type)) {
1243 return true;
1166 }1244 }
11671245
1168 // implicit conversion from non maybe type to maybe type1246 // implicit conversion from non maybe type to maybe type
1169 if (expected_type->id == TypeTableEntryIdMaybe) {1247 if (expected_type->id == TypeTableEntryIdMaybe &&
1170 TypeTableEntry *resolved_type = resolve_type_compatibility(g, context, node,1248 types_match_with_implicit_cast(g, expected_type->data.maybe.child_type, actual_type,
1171 expected_type->data.maybe.child_type, actual_type);1249 literal_node, reported_err))
1172 if (resolved_type->id == TypeTableEntryIdInvalid) {1250 {
1173 return resolved_type;1251 return true;
1174 }
1175 Expr *expr = get_resolved_expr(node);
1176 expr->implicit_maybe_cast.op = CastOpMaybeWrap;
1177 expr->implicit_maybe_cast.after_type = expected_type;
1178 expr->implicit_maybe_cast.source_node = node;
1179 context->cast_expr_alloca_list.append(&expr->implicit_maybe_cast);
1180 return expected_type;
1181 }1252 }
11821253
1183 // implicit widening conversion1254 // implicit widening conversion
...@@ -1186,78 +1257,94 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *cont...@@ -1186,78 +1257,94 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *cont
1186 expected_type->data.integral.is_signed == actual_type->data.integral.is_signed &&1257 expected_type->data.integral.is_signed == actual_type->data.integral.is_signed &&
1187 expected_type->size_in_bits >= actual_type->size_in_bits)1258 expected_type->size_in_bits >= actual_type->size_in_bits)
1188 {1259 {
1189 Expr *expr = get_resolved_expr(node);1260 return true;
1190 expr->implicit_cast.after_type = expected_type;
1191 expr->implicit_cast.op = CastOpIntWidenOrShorten;
1192 expr->implicit_cast.source_node = node;
1193 return expected_type;
1194 }1261 }
11951262
1196 // implicit constant sized array to unknown size array conversion1263 // implicit constant sized array to unknown size array conversion
1197 if (expected_type->id == TypeTableEntryIdStruct &&1264 if (expected_type->id == TypeTableEntryIdStruct &&
1198 expected_type->data.structure.is_unknown_size_array &&1265 expected_type->data.structure.is_unknown_size_array &&
1199 actual_type->id == TypeTableEntryIdArray &&1266 actual_type->id == TypeTableEntryIdArray &&
1200 actual_type->data.array.child_type == expected_type->data.structure.fields[0].type_entry->data.pointer.child_type)1267 types_match_const_cast_only(
1268 expected_type->data.structure.fields[0].type_entry->data.pointer.child_type,
1269 actual_type->data.array.child_type))
1201 {1270 {
1202 Expr *expr = get_resolved_expr(node);1271 return true;
1203 expr->implicit_cast.after_type = expected_type;
1204 expr->implicit_cast.op = CastOpToUnknownSizeArray;
1205 expr->implicit_cast.source_node = node;
1206 context->cast_expr_alloca_list.append(&expr->implicit_cast);
1207 return expected_type;
1208 }
1209
1210 // implicit non-const to const for pointers
1211 if (expected_type->id == TypeTableEntryIdPointer &&
1212 actual_type->id == TypeTableEntryIdPointer &&
1213 (!actual_type->data.pointer.is_const || expected_type->data.pointer.is_const))
1214 {
1215 TypeTableEntry *resolved_type = resolve_type_compatibility(g, context, node,
1216 expected_type->data.pointer.child_type,
1217 actual_type->data.pointer.child_type);
1218 if (resolved_type->id == TypeTableEntryIdInvalid) {
1219 return resolved_type;
1220 }
1221 return expected_type;
1222 }
1223
1224 // implicit non-const to const for unknown size arrays
1225 if (expected_type->id == TypeTableEntryIdStruct &&
1226 actual_type->id == TypeTableEntryIdStruct &&
1227 expected_type->data.structure.is_unknown_size_array &&
1228 actual_type->data.structure.is_unknown_size_array &&
1229 (!actual_type->data.structure.fields[0].type_entry->data.pointer.is_const ||
1230 expected_type->data.structure.fields[0].type_entry->data.pointer.is_const))
1231 {
1232 TypeTableEntry *resolved_type = resolve_type_compatibility(g, context, node,
1233 expected_type->data.structure.fields[0].type_entry->data.pointer.child_type,
1234 actual_type->data.structure.fields[0].type_entry->data.pointer.child_type);
1235 if (resolved_type->id == TypeTableEntryIdInvalid) {
1236 return resolved_type;
1237 }
1238 return expected_type;
1239 }1272 }
12401273
1274 // implicit number literal to typed number
1241 if ((actual_type->id == TypeTableEntryIdNumLitFloat ||1275 if ((actual_type->id == TypeTableEntryIdNumLitFloat ||
1242 actual_type->id == TypeTableEntryIdNumLitInt))1276 actual_type->id == TypeTableEntryIdNumLitInt))
1243 {1277 {
1244 if (num_lit_fits_in_other_type(g, node, expected_type)) {1278 if (num_lit_fits_in_other_type(g, literal_node, expected_type)) {
1245 return expected_type;1279 return true;
1246 } else {1280 } else {
1247 return g->builtin_types.entry_invalid;1281 *reported_err = true;
1248 }1282 }
1249 }1283 }
12501284
1251 add_node_error(g, first_executing_node(node),1285
1252 buf_sprintf("expected type '%s', got '%s'",1286 return false;
1253 buf_ptr(&expected_type->name),1287}
1254 buf_ptr(&actual_type->name)));1288
1289static AstNode *create_ast_node(CodeGen *g, ImportTableEntry *import, NodeType kind) {
1290 AstNode *node = allocate<AstNode>(1);
1291 node->type = kind;
1292 node->owner = import;
1293 node->create_index = g->next_node_index;
1294 g->next_node_index += 1;
1295 return node;
1296}
1297
1298static AstNode *create_ast_type_node(CodeGen *g, ImportTableEntry *import, TypeTableEntry *type_entry) {
1299 AstNode *node = create_ast_node(g, import, NodeTypeSymbol);
1300 node->data.symbol_expr.override_type_entry = type_entry;
1301 return node;
1302}
1303
1304static TypeTableEntry *create_and_analyze_cast_node(CodeGen *g, ImportTableEntry *import,
1305 BlockContext *context, TypeTableEntry *cast_to_type, AstNode *node)
1306{
1307 AstNode *new_parent_node = create_ast_node(g, import, NodeTypeFnCallExpr);
1308 *node->parent_field = new_parent_node;
1309 new_parent_node->parent_field = node->parent_field;
1310
1311 new_parent_node->data.fn_call_expr.fn_ref_expr = create_ast_type_node(g, import, cast_to_type);
1312 new_parent_node->data.fn_call_expr.params.append(node);
1313 normalize_parent_ptrs(new_parent_node);
1314
1315 return analyze_expression(g, import, context, cast_to_type, new_parent_node);
1316}
1317
1318static TypeTableEntry *resolve_type_compatibility(CodeGen *g, ImportTableEntry *import,
1319 BlockContext *context, AstNode *node,
1320 TypeTableEntry *expected_type, TypeTableEntry *actual_type)
1321{
1322 if (expected_type == nullptr)
1323 return actual_type; // anything will do
1324 if (expected_type == actual_type)
1325 return expected_type; // match
1326 if (expected_type->id == TypeTableEntryIdInvalid || actual_type->id == TypeTableEntryIdInvalid)
1327 return g->builtin_types.entry_invalid;
1328 if (actual_type->id == TypeTableEntryIdUnreachable)
1329 return actual_type;
1330
1331 bool reported_err = false;
1332 if (types_match_with_implicit_cast(g, expected_type, actual_type, node, &reported_err)) {
1333 return create_and_analyze_cast_node(g, import, context, expected_type, node);
1334 }
1335
1336 if (!reported_err) {
1337 add_node_error(g, first_executing_node(node),
1338 buf_sprintf("expected type '%s', got '%s'",
1339 buf_ptr(&expected_type->name),
1340 buf_ptr(&actual_type->name)));
1341 }
12551342
1256 return g->builtin_types.entry_invalid;1343 return g->builtin_types.entry_invalid;
1257}1344}
12581345
1259static TypeTableEntry *resolve_peer_type_compatibility(CodeGen *g, BlockContext *block_context,1346static TypeTableEntry *resolve_peer_type_compatibility(CodeGen *g, ImportTableEntry *import,
1260 AstNode *parent_source_node,1347 BlockContext *block_context, AstNode *parent_source_node,
1261 AstNode **child_nodes, TypeTableEntry **child_types, int child_count)1348 AstNode **child_nodes, TypeTableEntry **child_types, int child_count)
1262{1349{
1263 assert(child_count > 0);1350 assert(child_count > 0);
...@@ -1270,7 +1357,14 @@ static TypeTableEntry *resolve_peer_type_compatibility(CodeGen *g, BlockContext...@@ -1270,7 +1357,14 @@ static TypeTableEntry *resolve_peer_type_compatibility(CodeGen *g, BlockContext
1270 }1357 }
12711358
1272 for (int i = 0; i < child_count; i += 1) {1359 for (int i = 0; i < child_count; i += 1) {
1273 resolve_type_compatibility(g, block_context, child_nodes[i], expected_type, child_types[i]);1360 if (!child_nodes[i]) {
1361 continue;
1362 }
1363 Expr *expr = get_resolved_expr(child_nodes[i]);
1364 TypeTableEntry *resolved_type = resolve_type_compatibility(g, import, block_context,
1365 child_nodes[i], expected_type, child_types[i]);
1366 expr->type_entry = resolved_type;
1367 add_global_const_expr(g, expr);
1274 }1368 }
12751369
1276 return expected_type;1370 return expected_type;
...@@ -1667,13 +1761,7 @@ static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node,...@@ -1667,13 +1761,7 @@ static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node,
1667static TypeTableEntry *resolve_expr_const_val_as_other_expr(CodeGen *g, AstNode *node, AstNode *other) {1761static TypeTableEntry *resolve_expr_const_val_as_other_expr(CodeGen *g, AstNode *node, AstNode *other) {
1668 Expr *expr = get_resolved_expr(node);1762 Expr *expr = get_resolved_expr(node);
1669 Expr *other_expr = get_resolved_expr(other);1763 Expr *other_expr = get_resolved_expr(other);
1670 ConstExprValue *other_const_val;1764 expr->const_val = other_expr->const_val;
1671 if (other_expr->implicit_maybe_cast.after_type) {
1672 other_const_val = &other_expr->implicit_maybe_cast.const_val;
1673 } else {
1674 other_const_val = &other_expr->const_val;
1675 }
1676 expr->const_val = *other_const_val;
1677 return other_expr->type_entry;1765 return other_expr->type_entry;
1678}1766}
16791767
...@@ -1758,6 +1846,10 @@ static TypeTableEntry *resolve_expr_const_val_as_bignum_op(CodeGen *g, AstNode *...@@ -1758,6 +1846,10 @@ static TypeTableEntry *resolve_expr_const_val_as_bignum_op(CodeGen *g, AstNode *
1758static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,1846static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
1759 TypeTableEntry *expected_type, AstNode *node)1847 TypeTableEntry *expected_type, AstNode *node)
1760{1848{
1849 if (node->data.symbol_expr.override_type_entry) {
1850 return resolve_expr_const_val_as_type(g, node, node->data.symbol_expr.override_type_entry);
1851 }
1852
1761 Buf *variable_name = &node->data.symbol_expr.symbol;1853 Buf *variable_name = &node->data.symbol_expr.symbol;
17621854
1763 auto primitive_table_entry = g->primitive_type_table.maybe_get(variable_name);1855 auto primitive_table_entry = g->primitive_type_table.maybe_get(variable_name);
...@@ -1772,13 +1864,7 @@ static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import,...@@ -1772,13 +1864,7 @@ static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import,
1772 AstNode *decl_node = var->decl_node;1864 AstNode *decl_node = var->decl_node;
1773 if (decl_node->type == NodeTypeVariableDeclaration) {1865 if (decl_node->type == NodeTypeVariableDeclaration) {
1774 AstNode *expr_node = decl_node->data.variable_declaration.expr;1866 AstNode *expr_node = decl_node->data.variable_declaration.expr;
1775 Expr *other_expr = get_resolved_expr(expr_node);1867 ConstExprValue *other_const_val = &get_resolved_expr(expr_node)->const_val;
1776 ConstExprValue *other_const_val;
1777 if (other_expr->implicit_maybe_cast.after_type) {
1778 other_const_val = &other_expr->implicit_maybe_cast.const_val;
1779 } else {
1780 other_const_val = &other_expr->const_val;
1781 }
1782 if (other_const_val->ok) {1868 if (other_const_val->ok) {
1783 return resolve_expr_const_val_as_other_expr(g, node, expr_node);1869 return resolve_expr_const_val_as_other_expr(g, node, expr_node);
1784 }1870 }
...@@ -1955,7 +2041,7 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im...@@ -1955,7 +2041,7 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im
1955 AstNode *op_nodes[] = {op1, op2};2041 AstNode *op_nodes[] = {op1, op2};
1956 TypeTableEntry *op_types[] = {op1_type, op2_type};2042 TypeTableEntry *op_types[] = {op1_type, op2_type};
19572043
1958 TypeTableEntry *resolved_type = resolve_peer_type_compatibility(g, context, node,2044 TypeTableEntry *resolved_type = resolve_peer_type_compatibility(g, import, context, node,
1959 op_nodes, op_types, 2);2045 op_nodes, op_types, 2);
19602046
1961 if (resolved_type->id == TypeTableEntryIdInvalid) {2047 if (resolved_type->id == TypeTableEntryIdInvalid) {
...@@ -2109,7 +2195,7 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import,...@@ -2109,7 +2195,7 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import,
2109 AstNode *op_nodes[] = {op1, op2};2195 AstNode *op_nodes[] = {op1, op2};
2110 TypeTableEntry *op_types[] = {lhs_type, rhs_type};2196 TypeTableEntry *op_types[] = {lhs_type, rhs_type};
21112197
2112 TypeTableEntry *resolved_type = resolve_peer_type_compatibility(g, context, node,2198 TypeTableEntry *resolved_type = resolve_peer_type_compatibility(g, import, context, node,
2113 op_nodes, op_types, 2);2199 op_nodes, op_types, 2);
21142200
2115 if (resolved_type->id == TypeTableEntryIdInvalid) {2201 if (resolved_type->id == TypeTableEntryIdInvalid) {
...@@ -2162,6 +2248,7 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import,...@@ -2162,6 +2248,7 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import,
2162 add_node_error(g, op1,2248 add_node_error(g, op1,
2163 buf_sprintf("expected maybe type, got '%s'",2249 buf_sprintf("expected maybe type, got '%s'",
2164 buf_ptr(&lhs_type->name)));2250 buf_ptr(&lhs_type->name)));
2251 return g->builtin_types.entry_invalid;
2165 }2252 }
2166 }2253 }
2167 case BinOpTypeInvalid:2254 case BinOpTypeInvalid:
...@@ -2502,8 +2589,8 @@ static TypeTableEntry *analyze_if_then_else(CodeGen *g, ImportTableEntry *import...@@ -2502,8 +2589,8 @@ static TypeTableEntry *analyze_if_then_else(CodeGen *g, ImportTableEntry *import
2502 if (else_node) {2589 if (else_node) {
2503 else_type = analyze_expression(g, import, context, expected_type, else_node);2590 else_type = analyze_expression(g, import, context, expected_type, else_node);
2504 } else {2591 } else {
2505 else_type = g->builtin_types.entry_void;2592 else_type = resolve_type_compatibility(g, import, context, parent_node, expected_type,
2506 else_type = resolve_type_compatibility(g, context, parent_node, expected_type, else_type);2593 g->builtin_types.entry_void);
2507 }2594 }
25082595
25092596
...@@ -2512,7 +2599,7 @@ static TypeTableEntry *analyze_if_then_else(CodeGen *g, ImportTableEntry *import...@@ -2512,7 +2599,7 @@ static TypeTableEntry *analyze_if_then_else(CodeGen *g, ImportTableEntry *import
2512 } else {2599 } else {
2513 AstNode *op_nodes[] = {then_block, else_node};2600 AstNode *op_nodes[] = {then_block, else_node};
2514 TypeTableEntry *op_types[] = {then_type, else_type};2601 TypeTableEntry *op_types[] = {then_type, else_type};
2515 return resolve_peer_type_compatibility(g, context, parent_node, op_nodes, op_types, 2);2602 return resolve_peer_type_compatibility(g, import, context, parent_node, op_nodes, op_types, 2);
2516 }2603 }
2517}2604}
25182605
...@@ -2616,37 +2703,30 @@ static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *impor...@@ -2616,37 +2703,30 @@ static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *impor
2616 }2703 }
2617}2704}
26182705
2619static void eval_const_expr_implicit_cast(CodeGen *g, ImportTableEntry *import, BlockContext *context,2706static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *expr_node) {
2620 AstNode *node, Cast *cast, AstNode *expr_node)2707 assert(node->type == NodeTypeFnCallExpr);
2621{2708 ConstExprValue *other_val = &get_resolved_expr(expr_node)->const_val;
2622 switch (cast->op) {2709 ConstExprValue *const_val = &get_resolved_expr(node)->const_val;
2623 case CastOpNothing:2710 if (!other_val->ok) {
2711 return;
2712 }
2713 assert(other_val != const_val);
2714 switch (node->data.fn_call_expr.cast_op) {
2715 case CastOpNoCast:
2716 zig_unreachable();
2717 case CastOpNoop:
2624 case CastOpPtrToInt:2718 case CastOpPtrToInt:
2625 case CastOpIntWidenOrShorten:2719 case CastOpIntWidenOrShorten:
2626 case CastOpPointerReinterpret:2720 case CastOpPointerReinterpret:
2627 {2721 *const_val = *other_val;
2628 ConstExprValue *other_val = &get_resolved_expr(expr_node)->const_val;2722 break;
2629 ConstExprValue *const_val = &cast->const_val;
2630 assert(const_val != other_val);
2631 *const_val = *other_val;
2632 break;
2633 }
2634 case CastOpToUnknownSizeArray:2723 case CastOpToUnknownSizeArray:
2635 // TODO eval const expr2724 zig_panic("TODO CastOpToUnknownSizeArray");
2636 break;2725 break;
2637 case CastOpMaybeWrap:2726 case CastOpMaybeWrap:
2638 {2727 const_val->data.x_maybe = other_val;
2639 ConstExprValue *other_val = &get_resolved_expr(expr_node)->const_val;2728 const_val->ok = true;
2640 ConstExprValue *const_val = &cast->const_val;2729 break;
2641 if (!other_val->ok) {
2642 break;
2643 }
2644 assert(const_val != other_val);
2645
2646 const_val->data.x_maybe = other_val;
2647 const_val->ok = true;
2648 break;
2649 }
2650 }2730 }
2651}2731}
26522732
...@@ -2673,51 +2753,91 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B...@@ -2673,51 +2753,91 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
2673 return g->builtin_types.entry_invalid;2753 return g->builtin_types.entry_invalid;
2674 }2754 }
26752755
2676 Cast *cast = &node->data.fn_call_expr.cast;2756 // explicit match or non-const to const
2677 cast->source_node = node;2757 if (types_match_const_cast_only(wanted_type, actual_type)) {
2678 cast->after_type = wanted_type;2758 node->data.fn_call_expr.cast_op = CastOpNoop;
2759 eval_const_expr_implicit_cast(g, node, expr_node);
2760 return wanted_type;
2761 }
26792762
2763 // explicit cast from pointer to isize or usize
2680 if ((wanted_type == g->builtin_types.entry_isize || wanted_type == g->builtin_types.entry_usize) &&2764 if ((wanted_type == g->builtin_types.entry_isize || wanted_type == g->builtin_types.entry_usize) &&
2681 actual_type->id == TypeTableEntryIdPointer)2765 actual_type->id == TypeTableEntryIdPointer)
2682 {2766 {
2683 cast->op = CastOpPtrToInt;2767 node->data.fn_call_expr.cast_op = CastOpPtrToInt;
2684 eval_const_expr_implicit_cast(g, import, context, node, cast, expr_node);2768 eval_const_expr_implicit_cast(g, node, expr_node);
2685 return wanted_type;2769 return wanted_type;
2686 } else if (wanted_type->id == TypeTableEntryIdInt &&2770 }
2687 actual_type->id == TypeTableEntryIdInt)2771
2772 // explicit cast from any int to any other int
2773 if (wanted_type->id == TypeTableEntryIdInt &&
2774 actual_type->id == TypeTableEntryIdInt)
2688 {2775 {
2689 cast->op = CastOpIntWidenOrShorten;2776 node->data.fn_call_expr.cast_op = CastOpIntWidenOrShorten;
2690 eval_const_expr_implicit_cast(g, import, context, node, cast, expr_node);2777 eval_const_expr_implicit_cast(g, node, expr_node);
2691 return wanted_type;2778 return wanted_type;
2692 } else if (wanted_type->id == TypeTableEntryIdStruct &&2779 }
2693 wanted_type->data.structure.is_unknown_size_array &&2780
2694 actual_type->id == TypeTableEntryIdArray &&2781 // explicit cast from fixed size array to unknown size array
2695 actual_type->data.array.child_type == wanted_type->data.structure.fields[0].type_entry)2782 if (wanted_type->id == TypeTableEntryIdStruct &&
2783 wanted_type->data.structure.is_unknown_size_array &&
2784 actual_type->id == TypeTableEntryIdArray &&
2785 types_match_const_cast_only(
2786 wanted_type->data.structure.fields[0].type_entry->data.pointer.child_type,
2787 actual_type->data.array.child_type))
2696 {2788 {
2697 cast->op = CastOpToUnknownSizeArray;2789 node->data.fn_call_expr.cast_op = CastOpToUnknownSizeArray;
2698 context->cast_expr_alloca_list.append(cast);2790 context->cast_alloca_list.append(node);
2699 eval_const_expr_implicit_cast(g, import, context, node, cast, expr_node);2791 eval_const_expr_implicit_cast(g, node, expr_node);
2700 return wanted_type;2792 return wanted_type;
2701 } else if (actual_type->id == TypeTableEntryIdNumLitFloat ||2793 }
2702 actual_type->id == TypeTableEntryIdNumLitInt)2794
2795 // explicit cast from pointer to another pointer
2796 if (actual_type->id == TypeTableEntryIdPointer &&
2797 wanted_type->id == TypeTableEntryIdPointer)
2703 {2798 {
2704 num_lit_fits_in_other_type(g, expr_node, wanted_type);2799 node->data.fn_call_expr.cast_op = CastOpPointerReinterpret;
2705 cast->op = CastOpNothing;2800 eval_const_expr_implicit_cast(g, node, expr_node);
2706 eval_const_expr_implicit_cast(g, import, context, node, cast, expr_node);
2707 return wanted_type;2801 return wanted_type;
2708 } else if (actual_type->id == TypeTableEntryIdPointer &&2802 }
2709 wanted_type->id == TypeTableEntryIdPointer)2803
2804 // explicit cast from child type of maybe type to maybe type
2805 if (wanted_type->id == TypeTableEntryIdMaybe) {
2806 if (types_match_const_cast_only(wanted_type->data.maybe.child_type, actual_type)) {
2807 node->data.fn_call_expr.cast_op = CastOpMaybeWrap;
2808 eval_const_expr_implicit_cast(g, node, expr_node);
2809 return wanted_type;
2810 } else if (actual_type->id == TypeTableEntryIdNumLitInt ||
2811 actual_type->id == TypeTableEntryIdNumLitFloat)
2812 {
2813 if (num_lit_fits_in_other_type(g, expr_node, wanted_type->data.maybe.child_type)) {
2814 node->data.fn_call_expr.cast_op = CastOpMaybeWrap;
2815 eval_const_expr_implicit_cast(g, node, expr_node);
2816 return wanted_type;
2817 } else {
2818 return g->builtin_types.entry_invalid;
2819 }
2820 }
2821 }
2822
2823 // explicit cast from number literal to another type
2824 if (actual_type->id == TypeTableEntryIdNumLitFloat ||
2825 actual_type->id == TypeTableEntryIdNumLitInt)
2710 {2826 {
2711 cast->op = CastOpPointerReinterpret;2827 if (num_lit_fits_in_other_type(g, expr_node, wanted_type)) {
2712 eval_const_expr_implicit_cast(g, import, context, node, cast, expr_node);2828 node->data.fn_call_expr.cast_op = CastOpNoop;
2713 return wanted_type;2829 eval_const_expr_implicit_cast(g, node, expr_node);
2714 } else {2830 return wanted_type;
2715 add_node_error(g, node,2831 } else {
2716 buf_sprintf("invalid cast from type '%s' to '%s'",2832 return g->builtin_types.entry_invalid;
2717 buf_ptr(&actual_type->name),2833 }
2718 buf_ptr(&wanted_type->name)));
2719 return g->builtin_types.entry_invalid;
2720 }2834 }
2835
2836 add_node_error(g, node,
2837 buf_sprintf("invalid cast from type '%s' to '%s'",
2838 buf_ptr(&actual_type->name),
2839 buf_ptr(&wanted_type->name)));
2840 return g->builtin_types.entry_invalid;
2721}2841}
27222842
2723static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,2843static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
...@@ -3281,39 +3401,14 @@ static TypeTableEntry *analyze_return_expr(CodeGen *g, ImportTableEntry *import,...@@ -3281,39 +3401,14 @@ static TypeTableEntry *analyze_return_expr(CodeGen *g, ImportTableEntry *import,
3281 actual_return_type = g->builtin_types.entry_invalid;3401 actual_return_type = g->builtin_types.entry_invalid;
3282 }3402 }
32833403
3284 resolve_type_compatibility(g, context, node, expected_return_type, actual_return_type);3404 resolve_type_compatibility(g, import, context, node, expected_return_type, actual_return_type);
32853405
3286 return g->builtin_types.entry_unreachable;3406 return g->builtin_types.entry_unreachable;
3287}3407}
32883408
3289static bool type_has_codegen_value(TypeTableEntryId id) {3409// When you call analyze_expression, the node you pass might no longer be the child node
3290 switch (id) {3410// you thought it was due to implicit casting rewriting the AST.
3291 case TypeTableEntryIdInvalid:3411static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import, BlockContext *context,
3292 case TypeTableEntryIdMetaType:
3293 case TypeTableEntryIdVoid:
3294 case TypeTableEntryIdUnreachable:
3295 return false;
3296
3297 // TODO make num lits return false when we make implicit casts insert ast nodes
3298 case TypeTableEntryIdNumLitFloat:
3299 case TypeTableEntryIdNumLitInt:
3300
3301 case TypeTableEntryIdBool:
3302 case TypeTableEntryIdInt:
3303 case TypeTableEntryIdFloat:
3304 case TypeTableEntryIdPointer:
3305 case TypeTableEntryIdArray:
3306 case TypeTableEntryIdStruct:
3307 case TypeTableEntryIdMaybe:
3308 case TypeTableEntryIdError:
3309 case TypeTableEntryIdEnum:
3310 case TypeTableEntryIdFn:
3311 return true;
3312 }
3313 zig_unreachable();
3314}
3315
3316static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, BlockContext *context,
3317 TypeTableEntry *expected_type, AstNode *node)3412 TypeTableEntry *expected_type, AstNode *node)
3318{3413{
3319 TypeTableEntry *return_type = nullptr;3414 TypeTableEntry *return_type = nullptr;
...@@ -3494,39 +3589,19 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,...@@ -3494,39 +3589,19 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
3494 zig_unreachable();3589 zig_unreachable();
3495 }3590 }
3496 assert(return_type);3591 assert(return_type);
3497 resolve_type_compatibility(g, context, node, expected_type, return_type);3592 // resolve_type_compatibility might do implicit cast which means node is now a child
3593 // of the actual node that we want to return the type of.
3594 //AstNode **field = node->parent_field;
3595 TypeTableEntry *resolved_type = resolve_type_compatibility(g, import, context, node,
3596 expected_type, return_type);
34983597
3499 Expr *expr = get_resolved_expr(node);3598 Expr *expr = get_resolved_expr(node);
3500 if (!expr->resolved_type) {3599 expr->type_entry = return_type;
3501 expr->resolved_type = return_type;
3502 }
3503 expr->type_entry = expr->resolved_type;
3504 expr->block_context = context;3600 expr->block_context = context;
35053601
3506 if (expr->const_val.ok && type_has_codegen_value(expr->resolved_type->id)) {3602 add_global_const_expr(g, expr);
3507 g->global_const_list.append(expr);
3508 }
35093603
35103604 return resolved_type;
3511 if (expr->type_entry->id == TypeTableEntryIdUnreachable) {
3512 return expr->type_entry;
3513 }
3514
3515 /* TODO delete this code when we make implicit casts insert ast nodes
3516 Cast *cast_node = &expr->implicit_cast;
3517 if (cast_node->after_type) {
3518 eval_const_expr_implicit_cast(g, import, context, node, cast_node, node);
3519 expr->type_entry = cast_node->after_type;
3520 }
3521 */
3522
3523 Cast *cast_node = &expr->implicit_maybe_cast;
3524 if (cast_node->after_type) {
3525 eval_const_expr_implicit_cast(g, import, context, node, cast_node, node);
3526 expr->type_entry = cast_node->after_type;
3527 }
3528
3529 return expr->type_entry;
3530}3605}
35313606
3532static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNode *node) {3607static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNode *node) {
src/codegen.cpp+78-124
...@@ -71,8 +71,6 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa...@@ -71,8 +71,6 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa
71static LLVMValueRef gen_assign_raw(CodeGen *g, AstNode *source_node, BinOpType bin_op,71static LLVMValueRef gen_assign_raw(CodeGen *g, AstNode *source_node, BinOpType bin_op,
72 LLVMValueRef target_ref, LLVMValueRef value,72 LLVMValueRef target_ref, LLVMValueRef value,
73 TypeTableEntry *op1_type, TypeTableEntry *op2_type);73 TypeTableEntry *op1_type, TypeTableEntry *op2_type);
74static LLVMValueRef gen_bare_cast(CodeGen *g, AstNode *node, LLVMValueRef expr_val,
75 TypeTableEntry *actual_type, TypeTableEntry *wanted_type, Cast *cast_node);
7674
77static TypeTableEntry *get_type_for_type_node(AstNode *node) {75static TypeTableEntry *get_type_for_type_node(AstNode *node) {
78 Expr *expr = get_resolved_expr(node);76 Expr *expr = get_resolved_expr(node);
...@@ -111,17 +109,7 @@ static LLVMValueRef find_or_create_string(CodeGen *g, Buf *str, bool c) {...@@ -111,17 +109,7 @@ static LLVMValueRef find_or_create_string(CodeGen *g, Buf *str, bool c) {
111}109}
112110
113static TypeTableEntry *get_expr_type(AstNode *node) {111static TypeTableEntry *get_expr_type(AstNode *node) {
114 Expr *expr = get_resolved_expr(node);112 return get_resolved_expr(node)->type_entry;
115 if (expr->implicit_maybe_cast.after_type) {
116 return expr->implicit_maybe_cast.after_type;
117 }
118 if (expr->implicit_cast.after_type) {
119 return expr->implicit_cast.after_type;
120 }
121 if (expr->resolved_type) {
122 return expr->resolved_type;
123 }
124 return expr->type_entry;
125}113}
126114
127static TypeTableEntry *fn_proto_type_from_type_node(CodeGen *g, AstNode *type_node) {115static TypeTableEntry *fn_proto_type_from_type_node(CodeGen *g, AstNode *type_node) {
...@@ -305,18 +293,84 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {...@@ -305,18 +293,84 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
305 TypeTableEntry *actual_type = get_expr_type(expr_node);293 TypeTableEntry *actual_type = get_expr_type(expr_node);
306 TypeTableEntry *wanted_type = get_expr_type(node);294 TypeTableEntry *wanted_type = get_expr_type(node);
307295
308 Cast *cast_node = &node->data.fn_call_expr.cast;296 AstNodeFnCallExpr *cast_expr = &node->data.fn_call_expr;
297
298 switch (cast_expr->cast_op) {
299 case CastOpNoCast:
300 zig_unreachable();
301 case CastOpNoop:
302 return expr_val;
303 case CastOpMaybeWrap:
304 {
305 assert(cast_expr->tmp_ptr);
306 assert(wanted_type->id == TypeTableEntryIdMaybe);
307 assert(actual_type);
308
309 add_debug_source_node(g, node);
310 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, 0, "");
311 gen_assign_raw(g, node, BinOpTypeAssign,
312 val_ptr, expr_val, wanted_type->data.maybe.child_type, actual_type);
313
314 add_debug_source_node(g, node);
315 LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, 1, "");
316 LLVMBuildStore(g->builder, LLVMConstAllOnes(LLVMInt1Type()), maybe_ptr);
317
318 return cast_expr->tmp_ptr;
319 }
320 case CastOpPtrToInt:
321 add_debug_source_node(g, node);
322 return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, "");
323 case CastOpPointerReinterpret:
324 add_debug_source_node(g, node);
325 return LLVMBuildBitCast(g->builder, expr_val, wanted_type->type_ref, "");
326 case CastOpIntWidenOrShorten:
327 if (actual_type->size_in_bits == wanted_type->size_in_bits) {
328 return expr_val;
329 } else if (actual_type->size_in_bits < wanted_type->size_in_bits) {
330 if (actual_type->data.integral.is_signed) {
331 add_debug_source_node(g, node);
332 return LLVMBuildSExt(g->builder, expr_val, wanted_type->type_ref, "");
333 } else {
334 add_debug_source_node(g, node);
335 return LLVMBuildZExt(g->builder, expr_val, wanted_type->type_ref, "");
336 }
337 } else {
338 assert(actual_type->size_in_bits > wanted_type->size_in_bits);
339 add_debug_source_node(g, node);
340 return LLVMBuildTrunc(g->builder, expr_val, wanted_type->type_ref, "");
341 }
342 case CastOpToUnknownSizeArray:
343 {
344 assert(cast_expr->tmp_ptr);
345 assert(wanted_type->id == TypeTableEntryIdStruct);
346 assert(wanted_type->data.structure.is_unknown_size_array);
347
348 TypeTableEntry *pointer_type = wanted_type->data.structure.fields[0].type_entry;
349
350 add_debug_source_node(g, node);
309351
310 return gen_bare_cast(g, node, expr_val, actual_type, wanted_type, cast_node);352 LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, 0, "");
353 LLVMValueRef expr_bitcast = LLVMBuildBitCast(g->builder, expr_val, pointer_type->type_ref, "");
354 LLVMBuildStore(g->builder, expr_bitcast, ptr_ptr);
311355
356 LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, 1, "");
357 LLVMValueRef len_val = LLVMConstInt(g->builtin_types.entry_isize->type_ref,
358 actual_type->data.array.len, false);
359 LLVMBuildStore(g->builder, len_val, len_ptr);
360
361 return cast_expr->tmp_ptr;
362 }
363 }
364 zig_unreachable();
312}365}
313366
367
314static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {368static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {
315 assert(node->type == NodeTypeFnCallExpr);369 assert(node->type == NodeTypeFnCallExpr);
316370
317 if (node->data.fn_call_expr.is_builtin) {371 if (node->data.fn_call_expr.is_builtin) {
318 return gen_builtin_fn_call_expr(g, node);372 return gen_builtin_fn_call_expr(g, node);
319 } else if (node->data.fn_call_expr.cast.after_type) {373 } else if (node->data.fn_call_expr.cast_op != CastOpNoCast) {
320 return gen_cast_expr(g, node);374 return gen_cast_expr(g, node);
321 }375 }
322376
...@@ -752,74 +806,6 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {...@@ -752,74 +806,6 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
752 zig_unreachable();806 zig_unreachable();
753}807}
754808
755static LLVMValueRef gen_bare_cast(CodeGen *g, AstNode *node, LLVMValueRef expr_val,
756 TypeTableEntry *actual_type, TypeTableEntry *wanted_type, Cast *cast_node)
757{
758 switch (cast_node->op) {
759 case CastOpNothing:
760 return expr_val;
761 case CastOpMaybeWrap:
762 {
763 assert(cast_node->ptr);
764 assert(wanted_type->id == TypeTableEntryIdMaybe);
765 assert(actual_type);
766
767 add_debug_source_node(g, node);
768 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, cast_node->ptr, 0, "");
769 gen_assign_raw(g, node, BinOpTypeAssign,
770 val_ptr, expr_val, wanted_type->data.maybe.child_type, actual_type);
771
772 add_debug_source_node(g, node);
773 LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, cast_node->ptr, 1, "");
774 LLVMBuildStore(g->builder, LLVMConstAllOnes(LLVMInt1Type()), maybe_ptr);
775
776 return cast_node->ptr;
777 }
778 case CastOpPtrToInt:
779 add_debug_source_node(g, node);
780 return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, "");
781 case CastOpPointerReinterpret:
782 add_debug_source_node(g, node);
783 return LLVMBuildBitCast(g->builder, expr_val, wanted_type->type_ref, "");
784 case CastOpIntWidenOrShorten:
785 if (actual_type->size_in_bits == wanted_type->size_in_bits) {
786 return expr_val;
787 } else if (actual_type->size_in_bits < wanted_type->size_in_bits) {
788 if (actual_type->data.integral.is_signed) {
789 add_debug_source_node(g, node);
790 return LLVMBuildSExt(g->builder, expr_val, wanted_type->type_ref, "");
791 } else {
792 add_debug_source_node(g, node);
793 return LLVMBuildZExt(g->builder, expr_val, wanted_type->type_ref, "");
794 }
795 } else {
796 assert(actual_type->size_in_bits > wanted_type->size_in_bits);
797 add_debug_source_node(g, node);
798 return LLVMBuildTrunc(g->builder, expr_val, wanted_type->type_ref, "");
799 }
800 case CastOpToUnknownSizeArray:
801 {
802 assert(cast_node->ptr);
803
804 TypeTableEntry *pointer_type = wanted_type->data.structure.fields[0].type_entry;
805
806 add_debug_source_node(g, node);
807
808 LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, cast_node->ptr, 0, "");
809 LLVMValueRef expr_bitcast = LLVMBuildBitCast(g->builder, expr_val, pointer_type->type_ref, "");
810 LLVMBuildStore(g->builder, expr_bitcast, ptr_ptr);
811
812 LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, cast_node->ptr, 1, "");
813 LLVMValueRef len_val = LLVMConstInt(g->builtin_types.entry_isize->type_ref,
814 actual_type->data.array.len, false);
815 LLVMBuildStore(g->builder, len_val, len_ptr);
816
817 return cast_node->ptr;
818 }
819 }
820 zig_unreachable();
821}
822
823static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node,809static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node,
824 LLVMValueRef val1, LLVMValueRef val2,810 LLVMValueRef val1, LLVMValueRef val2,
825 TypeTableEntry *op1_type, TypeTableEntry *op2_type,811 TypeTableEntry *op1_type, TypeTableEntry *op2_type,
...@@ -1970,7 +1956,7 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) {...@@ -1970,7 +1956,7 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) {
1970 return phi;1956 return phi;
1971}1957}
19721958
1973static LLVMValueRef gen_expr_no_cast(CodeGen *g, AstNode *node) {1959static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
1974 Expr *expr = get_resolved_expr(node);1960 Expr *expr = get_resolved_expr(node);
1975 if (expr->const_val.ok) {1961 if (expr->const_val.ok) {
1976 assert(expr->const_llvm_val);1962 assert(expr->const_llvm_val);
...@@ -2072,33 +2058,6 @@ static LLVMValueRef gen_expr_no_cast(CodeGen *g, AstNode *node) {...@@ -2072,33 +2058,6 @@ static LLVMValueRef gen_expr_no_cast(CodeGen *g, AstNode *node) {
2072 zig_unreachable();2058 zig_unreachable();
2073}2059}
20742060
2075static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
2076 LLVMValueRef val = gen_expr_no_cast(g, node);
2077
2078 if (is_node_void_expr(node)) {
2079 return val;
2080 }
2081
2082 Expr *expr = get_resolved_expr(node);
2083
2084 TypeTableEntry *before_type = expr->type_entry;
2085 if (before_type && before_type->id == TypeTableEntryIdUnreachable) {
2086 return val;
2087 }
2088 Cast *cast_node = &expr->implicit_cast;
2089 if (cast_node->after_type) {
2090 val = gen_bare_cast(g, node, val, before_type, cast_node->after_type, cast_node);
2091 before_type = cast_node->after_type;
2092 }
2093
2094 cast_node = &expr->implicit_maybe_cast;
2095 if (cast_node->after_type) {
2096 val = gen_bare_cast(g, node, val, before_type, cast_node->after_type, cast_node);
2097 }
2098
2099 return val;
2100}
2101
2102static void build_label_blocks(CodeGen *g, AstNode *block_node) {2061static void build_label_blocks(CodeGen *g, AstNode *block_node) {
2103 assert(block_node->type == NodeTypeBlock);2062 assert(block_node->type == NodeTypeBlock);
2104 for (int i = 0; i < block_node->data.block.statements.length; i += 1) {2063 for (int i = 0; i < block_node->data.block.statements.length; i += 1) {
...@@ -2180,14 +2139,7 @@ static void gen_const_globals(CodeGen *g) {...@@ -2180,14 +2139,7 @@ static void gen_const_globals(CodeGen *g) {
2180 Expr *expr = g->global_const_list.at(i);2139 Expr *expr = g->global_const_list.at(i);
2181 ConstExprValue *const_val = &expr->const_val;2140 ConstExprValue *const_val = &expr->const_val;
2182 assert(const_val->ok);2141 assert(const_val->ok);
2183 TypeTableEntry *type_entry = expr->resolved_type;2142 TypeTableEntry *type_entry = expr->type_entry;
2184
2185 // TODO delete this if when we make implicit casts insert ast nodes
2186 if (type_entry->id == TypeTableEntryIdNumLitFloat ||
2187 type_entry->id == TypeTableEntryIdNumLitInt)
2188 {
2189 continue;
2190 }
21912143
2192 if (handle_is_ptr(type_entry)) {2144 if (handle_is_ptr(type_entry)) {
2193 LLVMValueRef global_value = LLVMAddGlobal(g->module, type_entry->type_ref, "");2145 LLVMValueRef global_value = LLVMAddGlobal(g->module, type_entry->type_ref, "");
...@@ -2330,10 +2282,12 @@ static void do_code_gen(CodeGen *g) {...@@ -2330,10 +2282,12 @@ static void do_code_gen(CodeGen *g) {
2330 }2282 }
23312283
2332 // allocate structs which are the result of casts2284 // allocate structs which are the result of casts
2333 for (int cea_i = 0; cea_i < block_context->cast_expr_alloca_list.length; cea_i += 1) {2285 for (int cea_i = 0; cea_i < block_context->cast_alloca_list.length; cea_i += 1) {
2334 Cast *cast_node = block_context->cast_expr_alloca_list.at(cea_i);2286 AstNode *fn_call_node = block_context->cast_alloca_list.at(cea_i);
2335 add_debug_source_node(g, cast_node->source_node);2287 add_debug_source_node(g, fn_call_node);
2336 cast_node->ptr = LLVMBuildAlloca(g->builder, cast_node->after_type->type_ref, "");2288 Expr *expr = &fn_call_node->data.fn_call_expr.resolved_expr;
2289 fn_call_node->data.fn_call_expr.tmp_ptr = LLVMBuildAlloca(g->builder,
2290 expr->type_entry->type_ref, "");
2337 }2291 }
23382292
2339 // allocate structs which are struct value expressions2293 // allocate structs which are struct value expressions
src/parser.cpp+240-2
...@@ -173,6 +173,7 @@ void ast_print(AstNode *node, int indent) {...@@ -173,6 +173,7 @@ void ast_print(AstNode *node, int indent) {
173 for (int i = 0; i < indent; i += 1) {173 for (int i = 0; i < indent; i += 1) {
174 fprintf(stderr, " ");174 fprintf(stderr, " ");
175 }175 }
176 assert(node->type == NodeTypeRoot || *node->parent_field == node);
176177
177 switch (node->type) {178 switch (node->type) {
178 case NodeTypeRoot:179 case NodeTypeRoot:
...@@ -1008,6 +1009,7 @@ static AstNode *ast_parse_directive(ParseContext *pc, int *token_index) {...@@ -1008,6 +1009,7 @@ static AstNode *ast_parse_directive(ParseContext *pc, int *token_index) {
1008 *token_index += 1;1009 *token_index += 1;
1009 ast_expect_token(pc, r_paren, TokenIdRParen);1010 ast_expect_token(pc, r_paren, TokenIdRParen);
10101011
1012 normalize_parent_ptrs(node);
1011 return node;1013 return node;
1012}1014}
10131015
...@@ -1059,6 +1061,7 @@ static AstNode *ast_parse_param_decl(ParseContext *pc, int *token_index) {...@@ -1059,6 +1061,7 @@ static AstNode *ast_parse_param_decl(ParseContext *pc, int *token_index) {
10591061
1060 node->data.param_decl.type = ast_parse_prefix_op_expr(pc, token_index, true);1062 node->data.param_decl.type = ast_parse_prefix_op_expr(pc, token_index, true);
10611063
1064 normalize_parent_ptrs(node);
1062 return node;1065 return node;
1063}1066}
10641067
...@@ -1175,6 +1178,7 @@ static AstNode *ast_parse_array_type_expr(ParseContext *pc, int *token_index, bo...@@ -1175,6 +1178,7 @@ static AstNode *ast_parse_array_type_expr(ParseContext *pc, int *token_index, bo
11751178
1176 node->data.array_type.child_type = ast_parse_prefix_op_expr(pc, token_index, true);1179 node->data.array_type.child_type = ast_parse_prefix_op_expr(pc, token_index, true);
11771180
1181 normalize_parent_ptrs(node);
1178 return node;1182 return node;
1179}1183}
11801184
...@@ -1358,6 +1362,7 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, int *token_index, bool mand...@@ -1358,6 +1362,7 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, int *token_index, bool mand
1358 ast_expect_token(pc, rparen_tok, TokenIdRParen);1362 ast_expect_token(pc, rparen_tok, TokenIdRParen);
1359 *token_index += 1;1363 *token_index += 1;
13601364
1365 normalize_parent_ptrs(node);
1361 return node;1366 return node;
1362}1367}
13631368
...@@ -1416,6 +1421,8 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool...@@ -1416,6 +1421,8 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
1416 ast_eat_token(pc, token_index, TokenIdLParen);1421 ast_eat_token(pc, token_index, TokenIdLParen);
1417 ast_parse_fn_call_param_list(pc, token_index, &node->data.fn_call_expr.params);1422 ast_parse_fn_call_param_list(pc, token_index, &node->data.fn_call_expr.params);
1418 node->data.fn_call_expr.is_builtin = true;1423 node->data.fn_call_expr.is_builtin = true;
1424
1425 normalize_parent_ptrs(node);
1419 return node;1426 return node;
1420 } else if (token->id == TokenIdSymbol) {1427 } else if (token->id == TokenIdSymbol) {
1421 *token_index += 1;1428 *token_index += 1;
...@@ -1499,6 +1506,7 @@ static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc, int *token_index,...@@ -1499,6 +1506,7 @@ static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc, int *token_index,
1499 ast_buf_from_token(pc, field_name_tok, &field_node->data.struct_val_field.name);1506 ast_buf_from_token(pc, field_name_tok, &field_node->data.struct_val_field.name);
1500 field_node->data.struct_val_field.expr = ast_parse_expression(pc, token_index, true);1507 field_node->data.struct_val_field.expr = ast_parse_expression(pc, token_index, true);
15011508
1509 normalize_parent_ptrs(field_node);
1502 node->data.container_init_expr.entries.append(field_node);1510 node->data.container_init_expr.entries.append(field_node);
15031511
1504 Token *comma_tok = &pc->tokens->at(*token_index);1512 Token *comma_tok = &pc->tokens->at(*token_index);
...@@ -1545,6 +1553,7 @@ static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc, int *token_index,...@@ -1545,6 +1553,7 @@ static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc, int *token_index,
1545 }1553 }
1546 }1554 }
15471555
1556 normalize_parent_ptrs(node);
1548 prefix_op_expr = node;1557 prefix_op_expr = node;
1549 } else {1558 } else {
1550 return prefix_op_expr;1559 return prefix_op_expr;
...@@ -1575,6 +1584,7 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, int *token_index, boo...@@ -1575,6 +1584,7 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, int *token_index, boo
1575 node->data.fn_call_expr.fn_ref_expr = primary_expr;1584 node->data.fn_call_expr.fn_ref_expr = primary_expr;
1576 ast_parse_fn_call_param_list(pc, token_index, &node->data.fn_call_expr.params);1585 ast_parse_fn_call_param_list(pc, token_index, &node->data.fn_call_expr.params);
15771586
1587 normalize_parent_ptrs(node);
1578 primary_expr = node;1588 primary_expr = node;
1579 } else if (first_token->id == TokenIdLBracket) {1589 } else if (first_token->id == TokenIdLBracket) {
1580 *token_index += 1;1590 *token_index += 1;
...@@ -1599,6 +1609,7 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, int *token_index, boo...@@ -1599,6 +1609,7 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, int *token_index, boo
1599 node->data.slice_expr.is_const = true;1609 node->data.slice_expr.is_const = true;
1600 }1610 }
16011611
1612 normalize_parent_ptrs(node);
1602 primary_expr = node;1613 primary_expr = node;
1603 } else if (ellipsis_or_r_bracket->id == TokenIdRBracket) {1614 } else if (ellipsis_or_r_bracket->id == TokenIdRBracket) {
1604 *token_index += 1;1615 *token_index += 1;
...@@ -1607,6 +1618,7 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, int *token_index, boo...@@ -1607,6 +1618,7 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, int *token_index, boo
1607 node->data.array_access_expr.array_ref_expr = primary_expr;1618 node->data.array_access_expr.array_ref_expr = primary_expr;
1608 node->data.array_access_expr.subscript = expr_node;1619 node->data.array_access_expr.subscript = expr_node;
16091620
1621 normalize_parent_ptrs(node);
1610 primary_expr = node;1622 primary_expr = node;
1611 } else {1623 } else {
1612 ast_invalid_token_error(pc, first_token);1624 ast_invalid_token_error(pc, first_token);
...@@ -1620,6 +1632,7 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, int *token_index, boo...@@ -1620,6 +1632,7 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, int *token_index, boo
1620 node->data.field_access_expr.struct_expr = primary_expr;1632 node->data.field_access_expr.struct_expr = primary_expr;
1621 ast_buf_from_token(pc, name_token, &node->data.field_access_expr.field_name);1633 ast_buf_from_token(pc, name_token, &node->data.field_access_expr.field_name);
16221634
1635 normalize_parent_ptrs(node);
1623 primary_expr = node;1636 primary_expr = node;
1624 } else {1637 } else {
1625 return primary_expr;1638 return primary_expr;
...@@ -1677,6 +1690,8 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, boo...@@ -1677,6 +1690,8 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, int *token_index, boo
1677 node->data.prefix_op_expr.primary_expr = prefix_op_expr;1690 node->data.prefix_op_expr.primary_expr = prefix_op_expr;
1678 node->data.prefix_op_expr.prefix_op = prefix_op;1691 node->data.prefix_op_expr.prefix_op = prefix_op;
16791692
1693 normalize_parent_ptrs(node);
1694 normalize_parent_ptrs(parent_node);
1680 return parent_node;1695 return parent_node;
1681}1696}
16821697
...@@ -1728,6 +1743,7 @@ static AstNode *ast_parse_mult_expr(ParseContext *pc, int *token_index, bool man...@@ -1728,6 +1743,7 @@ static AstNode *ast_parse_mult_expr(ParseContext *pc, int *token_index, bool man
1728 node->data.bin_op_expr.bin_op = mult_op;1743 node->data.bin_op_expr.bin_op = mult_op;
1729 node->data.bin_op_expr.op2 = operand_2;1744 node->data.bin_op_expr.op2 = operand_2;
17301745
1746 normalize_parent_ptrs(node);
1731 operand_1 = node;1747 operand_1 = node;
1732 }1748 }
1733}1749}
...@@ -1778,6 +1794,7 @@ static AstNode *ast_parse_add_expr(ParseContext *pc, int *token_index, bool mand...@@ -1778,6 +1794,7 @@ static AstNode *ast_parse_add_expr(ParseContext *pc, int *token_index, bool mand
1778 node->data.bin_op_expr.bin_op = add_op;1794 node->data.bin_op_expr.bin_op = add_op;
1779 node->data.bin_op_expr.op2 = operand_2;1795 node->data.bin_op_expr.op2 = operand_2;
17801796
1797 normalize_parent_ptrs(node);
1781 operand_1 = node;1798 operand_1 = node;
1782 }1799 }
1783}1800}
...@@ -1828,6 +1845,7 @@ static AstNode *ast_parse_bit_shift_expr(ParseContext *pc, int *token_index, boo...@@ -1828,6 +1845,7 @@ static AstNode *ast_parse_bit_shift_expr(ParseContext *pc, int *token_index, boo
1828 node->data.bin_op_expr.bin_op = bit_shift_op;1845 node->data.bin_op_expr.bin_op = bit_shift_op;
1829 node->data.bin_op_expr.op2 = operand_2;1846 node->data.bin_op_expr.op2 = operand_2;
18301847
1848 normalize_parent_ptrs(node);
1831 operand_1 = node;1849 operand_1 = node;
1832 }1850 }
1833}1851}
...@@ -1854,6 +1872,7 @@ static AstNode *ast_parse_bin_and_expr(ParseContext *pc, int *token_index, bool...@@ -1854,6 +1872,7 @@ static AstNode *ast_parse_bin_and_expr(ParseContext *pc, int *token_index, bool
1854 node->data.bin_op_expr.bin_op = BinOpTypeBinAnd;1872 node->data.bin_op_expr.bin_op = BinOpTypeBinAnd;
1855 node->data.bin_op_expr.op2 = operand_2;1873 node->data.bin_op_expr.op2 = operand_2;
18561874
1875 normalize_parent_ptrs(node);
1857 operand_1 = node;1876 operand_1 = node;
1858 }1877 }
1859}1878}
...@@ -1879,6 +1898,7 @@ static AstNode *ast_parse_bin_xor_expr(ParseContext *pc, int *token_index, bool...@@ -1879,6 +1898,7 @@ static AstNode *ast_parse_bin_xor_expr(ParseContext *pc, int *token_index, bool
1879 node->data.bin_op_expr.bin_op = BinOpTypeBinXor;1898 node->data.bin_op_expr.bin_op = BinOpTypeBinXor;
1880 node->data.bin_op_expr.op2 = operand_2;1899 node->data.bin_op_expr.op2 = operand_2;
18811900
1901 normalize_parent_ptrs(node);
1882 operand_1 = node;1902 operand_1 = node;
1883 }1903 }
1884}1904}
...@@ -1904,6 +1924,7 @@ static AstNode *ast_parse_bin_or_expr(ParseContext *pc, int *token_index, bool m...@@ -1904,6 +1924,7 @@ static AstNode *ast_parse_bin_or_expr(ParseContext *pc, int *token_index, bool m
1904 node->data.bin_op_expr.bin_op = BinOpTypeBinOr;1924 node->data.bin_op_expr.bin_op = BinOpTypeBinOr;
1905 node->data.bin_op_expr.op2 = operand_2;1925 node->data.bin_op_expr.op2 = operand_2;
19061926
1927 normalize_parent_ptrs(node);
1907 operand_1 = node;1928 operand_1 = node;
1908 }1929 }
1909}1930}
...@@ -1954,6 +1975,7 @@ static AstNode *ast_parse_comparison_expr(ParseContext *pc, int *token_index, bo...@@ -1954,6 +1975,7 @@ static AstNode *ast_parse_comparison_expr(ParseContext *pc, int *token_index, bo
1954 node->data.bin_op_expr.bin_op = cmp_op;1975 node->data.bin_op_expr.bin_op = cmp_op;
1955 node->data.bin_op_expr.op2 = operand_2;1976 node->data.bin_op_expr.op2 = operand_2;
19561977
1978 normalize_parent_ptrs(node);
1957 return node;1979 return node;
1958}1980}
19591981
...@@ -1978,6 +2000,7 @@ static AstNode *ast_parse_bool_and_expr(ParseContext *pc, int *token_index, bool...@@ -1978,6 +2000,7 @@ static AstNode *ast_parse_bool_and_expr(ParseContext *pc, int *token_index, bool
1978 node->data.bin_op_expr.bin_op = BinOpTypeBoolAnd;2000 node->data.bin_op_expr.bin_op = BinOpTypeBoolAnd;
1979 node->data.bin_op_expr.op2 = operand_2;2001 node->data.bin_op_expr.op2 = operand_2;
19802002
2003 normalize_parent_ptrs(node);
1981 operand_1 = node;2004 operand_1 = node;
1982 }2005 }
1983}2006}
...@@ -2043,6 +2066,8 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, int *token_index, bool manda...@@ -2043,6 +2066,8 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, int *token_index, bool manda
2043 ast_eat_token(pc, token_index, TokenIdRParen);2066 ast_eat_token(pc, token_index, TokenIdRParen);
2044 node->data.if_var_expr.then_block = ast_parse_expression(pc, token_index, true);2067 node->data.if_var_expr.then_block = ast_parse_expression(pc, token_index, true);
2045 node->data.if_var_expr.else_node = ast_parse_else(pc, token_index, false);2068 node->data.if_var_expr.else_node = ast_parse_else(pc, token_index, false);
2069
2070 normalize_parent_ptrs(node);
2046 return node;2071 return node;
2047 } else {2072 } else {
2048 AstNode *node = ast_create_node(pc, NodeTypeIfBoolExpr, if_tok);2073 AstNode *node = ast_create_node(pc, NodeTypeIfBoolExpr, if_tok);
...@@ -2050,6 +2075,8 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, int *token_index, bool manda...@@ -2050,6 +2075,8 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, int *token_index, bool manda
2050 ast_eat_token(pc, token_index, TokenIdRParen);2075 ast_eat_token(pc, token_index, TokenIdRParen);
2051 node->data.if_bool_expr.then_block = ast_parse_expression(pc, token_index, true);2076 node->data.if_bool_expr.then_block = ast_parse_expression(pc, token_index, true);
2052 node->data.if_bool_expr.else_node = ast_parse_else(pc, token_index, false);2077 node->data.if_bool_expr.else_node = ast_parse_else(pc, token_index, false);
2078
2079 normalize_parent_ptrs(node);
2053 return node;2080 return node;
2054 }2081 }
2055}2082}
...@@ -2094,6 +2121,8 @@ static AstNode *ast_parse_return_expr(ParseContext *pc, int *token_index, bool m...@@ -2094,6 +2121,8 @@ static AstNode *ast_parse_return_expr(ParseContext *pc, int *token_index, bool m
2094 AstNode *node = ast_create_node(pc, NodeTypeReturnExpr, token);2121 AstNode *node = ast_create_node(pc, NodeTypeReturnExpr, token);
2095 node->data.return_expr.kind = kind;2122 node->data.return_expr.kind = kind;
2096 node->data.return_expr.expr = ast_parse_expression(pc, token_index, false);2123 node->data.return_expr.expr = ast_parse_expression(pc, token_index, false);
2124
2125 normalize_parent_ptrs(node);
2097 return node;2126 return node;
2098}2127}
20992128
...@@ -2156,6 +2185,8 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, int *token...@@ -2156,6 +2185,8 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, int *token
2156 *token_index += 1;2185 *token_index += 1;
2157 if (eq_or_colon->id == TokenIdEq) {2186 if (eq_or_colon->id == TokenIdEq) {
2158 node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true);2187 node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true);
2188
2189 normalize_parent_ptrs(node);
2159 return node;2190 return node;
2160 } else if (eq_or_colon->id == TokenIdColon) {2191 } else if (eq_or_colon->id == TokenIdColon) {
2161 node->data.variable_declaration.type = ast_parse_prefix_op_expr(pc, token_index, true);2192 node->data.variable_declaration.type = ast_parse_prefix_op_expr(pc, token_index, true);
...@@ -2165,6 +2196,8 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, int *token...@@ -2165,6 +2196,8 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, int *token
21652196
2166 node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true);2197 node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true);
2167 }2198 }
2199
2200 normalize_parent_ptrs(node);
2168 return node;2201 return node;
2169 } else {2202 } else {
2170 ast_invalid_token_error(pc, eq_or_colon);2203 ast_invalid_token_error(pc, eq_or_colon);
...@@ -2192,6 +2225,7 @@ static AstNode *ast_parse_bool_or_expr(ParseContext *pc, int *token_index, bool...@@ -2192,6 +2225,7 @@ static AstNode *ast_parse_bool_or_expr(ParseContext *pc, int *token_index, bool
2192 node->data.bin_op_expr.bin_op = BinOpTypeBoolOr;2225 node->data.bin_op_expr.bin_op = BinOpTypeBoolOr;
2193 node->data.bin_op_expr.op2 = operand_2;2226 node->data.bin_op_expr.op2 = operand_2;
21942227
2228 normalize_parent_ptrs(node);
2195 operand_1 = node;2229 operand_1 = node;
2196 }2230 }
2197}2231}
...@@ -2220,7 +2254,7 @@ static AstNode *ast_parse_while_expr(ParseContext *pc, int *token_index, bool ma...@@ -2220,7 +2254,7 @@ static AstNode *ast_parse_while_expr(ParseContext *pc, int *token_index, bool ma
2220 node->data.while_expr.body = ast_parse_expression(pc, token_index, true);2254 node->data.while_expr.body = ast_parse_expression(pc, token_index, true);
22212255
22222256
22232257 normalize_parent_ptrs(node);
2224 return node;2258 return node;
2225}2259}
22262260
...@@ -2262,6 +2296,8 @@ static AstNode *ast_parse_for_expr(ParseContext *pc, int *token_index, bool mand...@@ -2262,6 +2296,8 @@ static AstNode *ast_parse_for_expr(ParseContext *pc, int *token_index, bool mand
2262 ast_eat_token(pc, token_index, TokenIdRParen);2296 ast_eat_token(pc, token_index, TokenIdRParen);
22632297
2264 node->data.for_expr.body = ast_parse_expression(pc, token_index, true);2298 node->data.for_expr.body = ast_parse_expression(pc, token_index, true);
2299
2300 normalize_parent_ptrs(node);
2265 return node;2301 return node;
2266}2302}
22672303
...@@ -2294,6 +2330,8 @@ static AstNode *ast_parse_switch_expr(ParseContext *pc, int *token_index, bool m...@@ -2294,6 +2330,8 @@ static AstNode *ast_parse_switch_expr(ParseContext *pc, int *token_index, bool m
22942330
2295 if (token->id == TokenIdRBrace) {2331 if (token->id == TokenIdRBrace) {
2296 *token_index += 1;2332 *token_index += 1;
2333
2334 normalize_parent_ptrs(node);
2297 return node;2335 return node;
2298 }2336 }
22992337
...@@ -2313,6 +2351,8 @@ static AstNode *ast_parse_switch_expr(ParseContext *pc, int *token_index, bool m...@@ -2313,6 +2351,8 @@ static AstNode *ast_parse_switch_expr(ParseContext *pc, int *token_index, bool m
23132351
2314 range_node->data.switch_range.start = expr1;2352 range_node->data.switch_range.start = expr1;
2315 range_node->data.switch_range.end = ast_parse_expression(pc, token_index, true);2353 range_node->data.switch_range.end = ast_parse_expression(pc, token_index, true);
2354
2355 normalize_parent_ptrs(range_node);
2316 } else {2356 } else {
2317 prong_node->data.switch_prong.items.append(expr1);2357 prong_node->data.switch_prong.items.append(expr1);
2318 }2358 }
...@@ -2335,6 +2375,8 @@ static AstNode *ast_parse_switch_expr(ParseContext *pc, int *token_index, bool m...@@ -2335,6 +2375,8 @@ static AstNode *ast_parse_switch_expr(ParseContext *pc, int *token_index, bool m
2335 ast_eat_token(pc, token_index, TokenIdFatArrow);2375 ast_eat_token(pc, token_index, TokenIdFatArrow);
2336 prong_node->data.switch_prong.expr = ast_parse_expression(pc, token_index, true);2376 prong_node->data.switch_prong.expr = ast_parse_expression(pc, token_index, true);
2337 ast_eat_token(pc, token_index, TokenIdComma);2377 ast_eat_token(pc, token_index, TokenIdComma);
2378
2379 normalize_parent_ptrs(prong_node);
2338 }2380 }
2339}2381}
23402382
...@@ -2430,6 +2472,7 @@ static AstNode *ast_parse_unwrap_maybe_expr(ParseContext *pc, int *token_index,...@@ -2430,6 +2472,7 @@ static AstNode *ast_parse_unwrap_maybe_expr(ParseContext *pc, int *token_index,
2430 node->data.bin_op_expr.bin_op = BinOpTypeUnwrapMaybe;2472 node->data.bin_op_expr.bin_op = BinOpTypeUnwrapMaybe;
2431 node->data.bin_op_expr.op2 = rhs;2473 node->data.bin_op_expr.op2 = rhs;
24322474
2475 normalize_parent_ptrs(node);
2433 return node;2476 return node;
2434}2477}
24352478
...@@ -2453,6 +2496,7 @@ static AstNode *ast_parse_ass_expr(ParseContext *pc, int *token_index, bool mand...@@ -2453,6 +2496,7 @@ static AstNode *ast_parse_ass_expr(ParseContext *pc, int *token_index, bool mand
2453 node->data.bin_op_expr.bin_op = ass_op;2496 node->data.bin_op_expr.bin_op = ass_op;
2454 node->data.bin_op_expr.op2 = rhs;2497 node->data.bin_op_expr.op2 = rhs;
24552498
2499 normalize_parent_ptrs(node);
2456 return node;2500 return node;
2457}2501}
24582502
...@@ -2530,6 +2574,7 @@ static AstNode *ast_create_void_expr(ParseContext *pc, Token *token) {...@@ -2530,6 +2574,7 @@ static AstNode *ast_create_void_expr(ParseContext *pc, Token *token) {
2530 node->data.container_init_expr.type = ast_create_node(pc, NodeTypeSymbol, token);2574 node->data.container_init_expr.type = ast_create_node(pc, NodeTypeSymbol, token);
2531 node->data.container_init_expr.kind = ContainerInitKindArray;2575 node->data.container_init_expr.kind = ContainerInitKindArray;
2532 buf_init_from_str(&node->data.container_init_expr.type->data.symbol_expr.symbol, "void");2576 buf_init_from_str(&node->data.container_init_expr.type->data.symbol_expr.symbol, "void");
2577 normalize_parent_ptrs(node);
2533 return node;2578 return node;
2534}2579}
25352580
...@@ -2581,6 +2626,8 @@ static AstNode *ast_parse_block(ParseContext *pc, int *token_index, bool mandato...@@ -2581,6 +2626,8 @@ static AstNode *ast_parse_block(ParseContext *pc, int *token_index, bool mandato
2581 last_token = &pc->tokens->at(*token_index);2626 last_token = &pc->tokens->at(*token_index);
2582 if (last_token->id == TokenIdRBrace) {2627 if (last_token->id == TokenIdRBrace) {
2583 *token_index += 1;2628 *token_index += 1;
2629
2630 normalize_parent_ptrs(node);
2584 return node;2631 return node;
2585 } else if (!semicolon_expected) {2632 } else if (!semicolon_expected) {
2586 continue;2633 continue;
...@@ -2651,6 +2698,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, int *token_index, bool mand...@@ -2651,6 +2698,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, int *token_index, bool mand
2651 node->data.fn_proto.return_type = ast_create_void_type_node(pc, next_token);2698 node->data.fn_proto.return_type = ast_create_void_type_node(pc, next_token);
2652 }2699 }
26532700
2701 normalize_parent_ptrs(node);
2654 return node;2702 return node;
2655}2703}
26562704
...@@ -2667,6 +2715,7 @@ static AstNode *ast_parse_fn_def(ParseContext *pc, int *token_index, bool mandat...@@ -2667,6 +2715,7 @@ static AstNode *ast_parse_fn_def(ParseContext *pc, int *token_index, bool mandat
2667 ast_eat_token(pc, token_index, TokenIdFatArrow);2715 ast_eat_token(pc, token_index, TokenIdFatArrow);
2668 node->data.fn_def.body = ast_parse_block(pc, token_index, true);2716 node->data.fn_def.body = ast_parse_block(pc, token_index, true);
26692717
2718 normalize_parent_ptrs(node);
2670 return node;2719 return node;
2671}2720}
26722721
...@@ -2683,6 +2732,7 @@ static AstNode *ast_parse_fn_decl(ParseContext *pc, int *token_index) {...@@ -2683,6 +2732,7 @@ static AstNode *ast_parse_fn_decl(ParseContext *pc, int *token_index) {
2683 *token_index += 1;2732 *token_index += 1;
2684 ast_expect_token(pc, semicolon, TokenIdSemicolon);2733 ast_expect_token(pc, semicolon, TokenIdSemicolon);
26852734
2735 normalize_parent_ptrs(node);
2686 return node;2736 return node;
2687}2737}
26882738
...@@ -2725,6 +2775,8 @@ static AstNode *ast_parse_extern_block(ParseContext *pc, int *token_index, bool...@@ -2725,6 +2775,8 @@ static AstNode *ast_parse_extern_block(ParseContext *pc, int *token_index, bool
2725 pc->directive_list = nullptr;2775 pc->directive_list = nullptr;
27262776
2727 *token_index += 1;2777 *token_index += 1;
2778
2779 normalize_parent_ptrs(node);
2728 return node;2780 return node;
2729 } else {2781 } else {
2730 AstNode *child = ast_parse_fn_decl(pc, token_index);2782 AstNode *child = ast_parse_fn_decl(pc, token_index);
...@@ -2768,6 +2820,7 @@ static AstNode *ast_parse_root_export_decl(ParseContext *pc, int *token_index, b...@@ -2768,6 +2820,7 @@ static AstNode *ast_parse_root_export_decl(ParseContext *pc, int *token_index, b
2768 *token_index += 1;2820 *token_index += 1;
2769 ast_expect_token(pc, semicolon, TokenIdSemicolon);2821 ast_expect_token(pc, semicolon, TokenIdSemicolon);
27702822
2823 normalize_parent_ptrs(node);
2771 return node;2824 return node;
2772}2825}
27732826
...@@ -2795,6 +2848,7 @@ static AstNode *ast_parse_use(ParseContext *pc, int *token_index) {...@@ -2795,6 +2848,7 @@ static AstNode *ast_parse_use(ParseContext *pc, int *token_index) {
2795 node->data.use.directives = pc->directive_list;2848 node->data.use.directives = pc->directive_list;
2796 pc->directive_list = nullptr;2849 pc->directive_list = nullptr;
27972850
2851 normalize_parent_ptrs(node);
2798 return node;2852 return node;
2799}2853}
28002854
...@@ -2895,12 +2949,13 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) {...@@ -2895,12 +2949,13 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) {
2895 }2949 }
28962950
2897 node->data.struct_decl.fields.append(field_node);2951 node->data.struct_decl.fields.append(field_node);
2952 normalize_parent_ptrs(field_node);
2898 } else {2953 } else {
2899 ast_invalid_token_error(pc, token);2954 ast_invalid_token_error(pc, token);
2900 }2955 }
2901 }2956 }
29022957
29032958 normalize_parent_ptrs(node);
2904 return node;2959 return node;
2905}2960}
29062961
...@@ -2948,6 +3003,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, b...@@ -2948,6 +3003,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, b
2948 node->data.error_value_decl.visib_mod = visib_mod;3003 node->data.error_value_decl.visib_mod = visib_mod;
2949 ast_buf_from_token(pc, name_tok, &node->data.error_value_decl.name);3004 ast_buf_from_token(pc, name_tok, &node->data.error_value_decl.name);
29503005
3006 normalize_parent_ptrs(node);
2951 return node;3007 return node;
2952}3008}
29533009
...@@ -3026,6 +3082,7 @@ static AstNode *ast_parse_root(ParseContext *pc, int *token_index) {...@@ -3026,6 +3082,7 @@ static AstNode *ast_parse_root(ParseContext *pc, int *token_index) {
3026 ast_invalid_token_error(pc, &pc->tokens->at(*token_index));3082 ast_invalid_token_error(pc, &pc->tokens->at(*token_index));
3027 }3083 }
30283084
3085 normalize_parent_ptrs(node);
3029 return node;3086 return node;
3030}3087}
30313088
...@@ -3042,3 +3099,184 @@ AstNode *ast_parse(Buf *buf, ZigList<Token> *tokens, ImportTableEntry *owner,...@@ -3042,3 +3099,184 @@ AstNode *ast_parse(Buf *buf, ZigList<Token> *tokens, ImportTableEntry *owner,
3042 pc.root = ast_parse_root(&pc, &token_index);3099 pc.root = ast_parse_root(&pc, &token_index);
3043 return pc.root;3100 return pc.root;
3044}3101}
3102
3103static void set_field(AstNode **field) {
3104 if (*field) {
3105 (*field)->parent_field = field;
3106 }
3107}
3108
3109static void set_list_fields(ZigList<AstNode*> *list) {
3110 for (int i = 0; i < list->length; i += 1) {
3111 set_field(&list->at(i));
3112 }
3113}
3114
3115void normalize_parent_ptrs(AstNode *node) {
3116 switch (node->type) {
3117 case NodeTypeRoot:
3118 set_list_fields(&node->data.root.top_level_decls);
3119 break;
3120 case NodeTypeRootExportDecl:
3121 set_list_fields(node->data.root_export_decl.directives);
3122 break;
3123 case NodeTypeFnProto:
3124 set_field(&node->data.fn_proto.return_type);
3125 set_list_fields(node->data.fn_proto.directives);
3126 set_list_fields(&node->data.fn_proto.params);
3127 break;
3128 case NodeTypeFnDef:
3129 set_field(&node->data.fn_def.fn_proto);
3130 set_field(&node->data.fn_def.body);
3131 break;
3132 case NodeTypeFnDecl:
3133 set_field(&node->data.fn_decl.fn_proto);
3134 break;
3135 case NodeTypeParamDecl:
3136 set_field(&node->data.param_decl.type);
3137 break;
3138 case NodeTypeBlock:
3139 set_list_fields(&node->data.block.statements);
3140 break;
3141 case NodeTypeExternBlock:
3142 set_list_fields(node->data.extern_block.directives);
3143 set_list_fields(&node->data.extern_block.fn_decls);
3144 break;
3145 case NodeTypeDirective:
3146 // none
3147 break;
3148 case NodeTypeReturnExpr:
3149 set_field(&node->data.return_expr.expr);
3150 break;
3151 case NodeTypeVariableDeclaration:
3152 set_field(&node->data.variable_declaration.type);
3153 set_field(&node->data.variable_declaration.expr);
3154 break;
3155 case NodeTypeErrorValueDecl:
3156 // none
3157 break;
3158 case NodeTypeBinOpExpr:
3159 set_field(&node->data.bin_op_expr.op1);
3160 set_field(&node->data.bin_op_expr.op2);
3161 break;
3162 case NodeTypeNumberLiteral:
3163 // none
3164 break;
3165 case NodeTypeStringLiteral:
3166 // none
3167 break;
3168 case NodeTypeCharLiteral:
3169 // none
3170 break;
3171 case NodeTypeErrorLiteral:
3172 // none
3173 break;
3174 case NodeTypeSymbol:
3175 // none
3176 break;
3177 case NodeTypePrefixOpExpr:
3178 set_field(&node->data.prefix_op_expr.primary_expr);
3179 break;
3180 case NodeTypeFnCallExpr:
3181 set_field(&node->data.fn_call_expr.fn_ref_expr);
3182 set_list_fields(&node->data.fn_call_expr.params);
3183 break;
3184 case NodeTypeArrayAccessExpr:
3185 set_field(&node->data.array_access_expr.array_ref_expr);
3186 set_field(&node->data.array_access_expr.subscript);
3187 break;
3188 case NodeTypeSliceExpr:
3189 set_field(&node->data.slice_expr.array_ref_expr);
3190 set_field(&node->data.slice_expr.start);
3191 set_field(&node->data.slice_expr.end);
3192 break;
3193 case NodeTypeFieldAccessExpr:
3194 set_field(&node->data.field_access_expr.struct_expr);
3195 break;
3196 case NodeTypeUse:
3197 set_list_fields(node->data.use.directives);
3198 break;
3199 case NodeTypeBoolLiteral:
3200 // none
3201 break;
3202 case NodeTypeNullLiteral:
3203 // none
3204 break;
3205 case NodeTypeIfBoolExpr:
3206 set_field(&node->data.if_bool_expr.condition);
3207 set_field(&node->data.if_bool_expr.then_block);
3208 set_field(&node->data.if_bool_expr.else_node);
3209 break;
3210 case NodeTypeIfVarExpr:
3211 set_field(&node->data.if_var_expr.var_decl.type);
3212 set_field(&node->data.if_var_expr.var_decl.expr);
3213 set_field(&node->data.if_var_expr.then_block);
3214 set_field(&node->data.if_var_expr.else_node);
3215 break;
3216 case NodeTypeWhileExpr:
3217 set_field(&node->data.while_expr.condition);
3218 set_field(&node->data.while_expr.body);
3219 break;
3220 case NodeTypeForExpr:
3221 set_field(&node->data.for_expr.elem_node);
3222 set_field(&node->data.for_expr.array_expr);
3223 set_field(&node->data.for_expr.index_node);
3224 set_field(&node->data.for_expr.body);
3225 break;
3226 case NodeTypeSwitchExpr:
3227 set_field(&node->data.switch_expr.expr);
3228 set_list_fields(&node->data.switch_expr.prongs);
3229 break;
3230 case NodeTypeSwitchProng:
3231 set_list_fields(&node->data.switch_prong.items);
3232 set_field(&node->data.switch_prong.var_symbol);
3233 set_field(&node->data.switch_prong.expr);
3234 break;
3235 case NodeTypeSwitchRange:
3236 set_field(&node->data.switch_range.start);
3237 set_field(&node->data.switch_range.end);
3238 break;
3239 case NodeTypeLabel:
3240 // none
3241 break;
3242 case NodeTypeGoto:
3243 // none
3244 break;
3245 case NodeTypeBreak:
3246 // none
3247 break;
3248 case NodeTypeContinue:
3249 // none
3250 break;
3251 case NodeTypeAsmExpr:
3252 for (int i = 0; i < node->data.asm_expr.input_list.length; i += 1) {
3253 AsmInput *asm_input = node->data.asm_expr.input_list.at(i);
3254 set_field(&asm_input->expr);
3255 }
3256 for (int i = 0; i < node->data.asm_expr.output_list.length; i += 1) {
3257 AsmOutput *asm_output = node->data.asm_expr.output_list.at(i);
3258 set_field(&asm_output->return_type);
3259 }
3260 break;
3261 case NodeTypeStructDecl:
3262 set_list_fields(&node->data.struct_decl.fields);
3263 set_list_fields(&node->data.struct_decl.fns);
3264 set_list_fields(node->data.struct_decl.directives);
3265 break;
3266 case NodeTypeStructField:
3267 set_field(&node->data.struct_field.type);
3268 set_list_fields(node->data.struct_field.directives);
3269 break;
3270 case NodeTypeContainerInitExpr:
3271 set_field(&node->data.container_init_expr.type);
3272 set_list_fields(&node->data.container_init_expr.entries);
3273 break;
3274 case NodeTypeStructValueField:
3275 set_field(&node->data.struct_val_field.expr);
3276 break;
3277 case NodeTypeArrayType:
3278 set_field(&node->data.array_type.size);
3279 set_field(&node->data.array_type.child_type);
3280 break;
3281 }
3282}
src/parser.hpp+2
...@@ -24,4 +24,6 @@ const char *node_type_str(NodeType node_type);...@@ -24,4 +24,6 @@ const char *node_type_str(NodeType node_type);
2424
25void ast_print(AstNode *node, int indent);25void ast_print(AstNode *node, int indent);
2626
27void normalize_parent_ptrs(AstNode *node);
28
27#endif29#endif
test/run_tests.cpp+1-1
...@@ -1317,7 +1317,7 @@ fn f() i32 => {...@@ -1317,7 +1317,7 @@ fn f() i32 => {
1317 const a = c"a";1317 const a = c"a";
1318 a1318 a
1319}1319}
1320 )SOURCE", 1, ".tmp_source.zig:2:15: error: expected type 'i32', got '&const u8'");1320 )SOURCE", 1, ".tmp_source.zig:4:5: error: expected type 'i32', got '&const u8'");
13211321
1322 add_compile_fail_case("if condition is bool, not int", R"SOURCE(1322 add_compile_fail_case("if condition is bool, not int", R"SOURCE(
1323fn f() => {1323fn f() => {