| ... | @@ -1318,6 +1318,16 @@ static TypeStructField *find_struct_type_field(TypeTableEntry *type_entry, Buf * | ... | @@ -1318,6 +1318,16 @@ static TypeStructField *find_struct_type_field(TypeTableEntry *type_entry, Buf * |
| 1318 | return nullptr; | 1318 | return nullptr; |
| 1319 | } | 1319 | } |
| 1320 | | 1320 | |
| | 1321 | static const char *err_container_init_syntax_name(ContainerInitKind kind) { |
| | 1322 | switch (kind) { |
| | 1323 | case ContainerInitKindStruct: |
| | 1324 | return "struct"; |
| | 1325 | case ContainerInitKindArray: |
| | 1326 | return "array"; |
| | 1327 | } |
| | 1328 | zig_unreachable(); |
| | 1329 | } |
| | 1330 | |
| 1321 | static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 1331 | static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 1322 | AstNode *node) | 1332 | AstNode *node) |
| 1323 | { | 1333 | { |
| ... | @@ -1331,60 +1341,51 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry | ... | @@ -1331,60 +1341,51 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry |
| 1331 | | 1341 | |
| 1332 | if (container_type->id == TypeTableEntryIdInvalid) { | 1342 | if (container_type->id == TypeTableEntryIdInvalid) { |
| 1333 | return container_type; | 1343 | return container_type; |
| 1334 | } else if (container_type->id == TypeTableEntryIdStruct) { | 1344 | } else if (container_type->id == TypeTableEntryIdStruct && |
| 1335 | switch (kind) { | 1345 | kind == ContainerInitKindStruct) |
| 1336 | case ContainerInitKindStruct: | 1346 | { |
| 1337 | { | 1347 | StructValExprCodeGen *codegen = &container_init_expr->resolved_struct_val_expr; |
| 1338 | StructValExprCodeGen *codegen = &container_init_expr->resolved_struct_val_expr; | 1348 | codegen->type_entry = container_type; |
| 1339 | codegen->type_entry = container_type; | 1349 | codegen->source_node = node; |
| 1340 | codegen->source_node = node; | 1350 | context->struct_val_expr_alloca_list.append(codegen); |
| 1341 | context->struct_val_expr_alloca_list.append(codegen); | | |
| 1342 | | 1351 | |
| 1343 | | 1352 | |
| 1344 | int expr_field_count = container_init_expr->entries.length; | 1353 | int expr_field_count = container_init_expr->entries.length; |
| 1345 | int actual_field_count = container_type->data.structure.field_count; | 1354 | int actual_field_count = container_type->data.structure.field_count; |
| 1346 | | 1355 | |
| 1347 | int *field_use_counts = allocate<int>(actual_field_count); | 1356 | int *field_use_counts = allocate<int>(actual_field_count); |
| 1348 | for (int i = 0; i < expr_field_count; i += 1) { | 1357 | for (int i = 0; i < expr_field_count; i += 1) { |
| 1349 | AstNode *val_field_node = container_init_expr->entries.at(i); | 1358 | AstNode *val_field_node = container_init_expr->entries.at(i); |
| 1350 | assert(val_field_node->type == NodeTypeStructValueField); | 1359 | assert(val_field_node->type == NodeTypeStructValueField); |
| 1351 | | 1360 | |
| 1352 | int field_index; | 1361 | int field_index; |
| 1353 | TypeStructField *type_field = find_struct_type_field(container_type, | 1362 | TypeStructField *type_field = find_struct_type_field(container_type, |
| 1354 | &val_field_node->data.struct_val_field.name, &field_index); | 1363 | &val_field_node->data.struct_val_field.name, &field_index); |
| 1355 | | 1364 | |
| 1356 | if (!type_field) { | 1365 | if (!type_field) { |
| 1357 | add_node_error(g, val_field_node, | 1366 | add_node_error(g, val_field_node, |
| 1358 | buf_sprintf("no member named '%s' in '%s'", | 1367 | buf_sprintf("no member named '%s' in '%s'", |
| 1359 | buf_ptr(&val_field_node->data.struct_val_field.name), buf_ptr(&container_type->name))); | 1368 | buf_ptr(&val_field_node->data.struct_val_field.name), buf_ptr(&container_type->name))); |
| 1360 | continue; | 1369 | continue; |
| 1361 | } | 1370 | } |
| 1362 | | 1371 | |
| 1363 | field_use_counts[field_index] += 1; | 1372 | field_use_counts[field_index] += 1; |
| 1364 | if (field_use_counts[field_index] > 1) { | 1373 | if (field_use_counts[field_index] > 1) { |
| 1365 | add_node_error(g, val_field_node, buf_sprintf("duplicate field")); | 1374 | add_node_error(g, val_field_node, buf_sprintf("duplicate field")); |
| 1366 | continue; | 1375 | continue; |
| 1367 | } | 1376 | } |
| 1368 | | 1377 | |
| 1369 | val_field_node->data.struct_val_field.type_struct_field = type_field; | 1378 | val_field_node->data.struct_val_field.type_struct_field = type_field; |
| 1370 | | 1379 | |
| 1371 | analyze_expression(g, import, context, type_field->type_entry, | 1380 | analyze_expression(g, import, context, type_field->type_entry, |
| 1372 | val_field_node->data.struct_val_field.expr); | 1381 | val_field_node->data.struct_val_field.expr); |
| 1373 | } | 1382 | } |
| 1374 | | 1383 | |
| 1375 | for (int i = 0; i < actual_field_count; i += 1) { | 1384 | for (int i = 0; i < actual_field_count; i += 1) { |
| 1376 | if (field_use_counts[i] == 0) { | 1385 | if (field_use_counts[i] == 0) { |
| 1377 | add_node_error(g, node, | | |
| 1378 | buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name))); | | |
| 1379 | } | | |
| 1380 | } | | |
| 1381 | break; | | |
| 1382 | } | | |
| 1383 | case ContainerInitKindArray: | | |
| 1384 | add_node_error(g, node, | 1386 | add_node_error(g, node, |
| 1385 | buf_sprintf("struct '%s' does not support array initialization syntax", | 1387 | buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name))); |
| 1386 | buf_ptr(&container_type->name))); | 1388 | } |
| 1387 | break; | | |
| 1388 | } | 1389 | } |
| 1389 | return container_type; | 1390 | return container_type; |
| 1390 | } else if (container_type->id == TypeTableEntryIdArray) { | 1391 | } else if (container_type->id == TypeTableEntryIdArray) { |
| ... | @@ -1409,7 +1410,8 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry | ... | @@ -1409,7 +1410,8 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry |
| 1409 | } | 1410 | } |
| 1410 | } else { | 1411 | } else { |
| 1411 | add_node_error(g, node, | 1412 | add_node_error(g, node, |
| 1412 | buf_sprintf("type '%s' does not support initialization syntax", buf_ptr(&container_type->name))); | 1413 | buf_sprintf("type '%s' does not support %s syntax", |
| | 1414 | buf_ptr(&container_type->name), err_container_init_syntax_name(kind))); |
| 1413 | return g->builtin_types.entry_invalid; | 1415 | return g->builtin_types.entry_invalid; |
| 1414 | } | 1416 | } |
| 1415 | } | 1417 | } |