| author | |
| committer | |
| log | 38f12adbda5d3b0114232fdccdbcc0b4179f9115 |
| tree | 5016bcd2cccea018738aa30c9bb7e91b2aaa9c2b |
| parent | ac630d354d51488d895bc14e26a069ae954ac5c6 |
3 files changed, 40 insertions(+), 8 deletions(-)
example/structs/structs.zig+3-1| ... | @@ -2,6 +2,8 @@ export executable "structs"; | ... | @@ -2,6 +2,8 @@ export executable "structs"; |
| 2 | 2 | ||
| 3 | use "std.zig"; | 3 | use "std.zig"; |
| 4 | 4 | ||
| 5 | // Note: this example is not working because codegen is confused about | ||
| 6 | // how byvalue structs which are in memory on the stack work | ||
| 5 | export fn main(argc : isize, argv : *mut *mut u8, env : *mut *mut u8) -> i32 { | 7 | export fn main(argc : isize, argv : *mut *mut u8, env : *mut *mut u8) -> i32 { |
| 6 | let mut foo : Foo; | 8 | let mut foo : Foo; |
| 7 | 9 | ||
| ... | @@ -22,6 +24,6 @@ struct Foo { | ... | @@ -22,6 +24,6 @@ struct Foo { |
| 22 | 24 | ||
| 23 | fn test_foo(foo : Foo) { | 25 | fn test_foo(foo : Foo) { |
| 24 | if foo.b { | 26 | if foo.b { |
| 25 | print_str("OK"); | 27 | print_str("OK" as string); |
| 26 | } | 28 | } |
| 27 | } | 29 | } |
src/analyze.cpp+18-2| ... | @@ -422,6 +422,9 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import, | ... | @@ -422,6 +422,9 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import, |
| 422 | type_entry->data.structure.fields = allocate<TypeStructField>(field_count); | 422 | type_entry->data.structure.fields = allocate<TypeStructField>(field_count); |
| 423 | 423 | ||
| 424 | LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count); | 424 | LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count); |
| 425 | LLVMZigDIType **di_element_types = allocate<LLVMZigDIType*>(field_count); | ||
| 426 | |||
| 427 | uint64_t total_size_in_bits = 0; | ||
| 425 | 428 | ||
| 426 | for (int i = 0; i < field_count; i += 1) { | 429 | for (int i = 0; i < field_count; i += 1) { |
| 427 | AstNode *field_node = node->data.struct_decl.fields.at(i); | 430 | AstNode *field_node = node->data.struct_decl.fields.at(i); |
| ... | @@ -429,12 +432,22 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import, | ... | @@ -429,12 +432,22 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import, |
| 429 | type_struct_field->name = &field_node->data.struct_field.name; | 432 | type_struct_field->name = &field_node->data.struct_field.name; |
| 430 | type_struct_field->type_entry = resolve_type(g, field_node->data.struct_field.type); | 433 | type_struct_field->type_entry = resolve_type(g, field_node->data.struct_field.type); |
| 431 | 434 | ||
| 435 | total_size_in_bits = type_struct_field->type_entry->size_in_bits; | ||
| 436 | di_element_types[i] = type_struct_field->type_entry->di_type; | ||
| 437 | |||
| 432 | element_types[i] = type_struct_field->type_entry->type_ref; | 438 | element_types[i] = type_struct_field->type_entry->type_ref; |
| 433 | } | 439 | } |
| 434 | // TODO align_in_bits and size_in_bits | ||
| 435 | // TODO set up ditype for the struct | ||
| 436 | LLVMStructSetBody(type_entry->type_ref, element_types, field_count, false); | 440 | LLVMStructSetBody(type_entry->type_ref, element_types, field_count, false); |
| 437 | 441 | ||
| 442 | // TODO re-evaluate this align in bits and size in bits | ||
| 443 | type_entry->align_in_bits = 0; | ||
| 444 | type_entry->size_in_bits = total_size_in_bits; | ||
| 445 | type_entry->di_type = LLVMZigCreateDebugStructType(g->dbuilder, | ||
| 446 | LLVMZigFileToScope(import->di_file), | ||
| 447 | buf_ptr(&node->data.struct_decl.name), | ||
| 448 | import->di_file, node->line + 1, type_entry->size_in_bits, type_entry->align_in_bits, 0, | ||
| 449 | nullptr, di_element_types, field_count, 0, nullptr, ""); | ||
| 450 | |||
| 438 | break; | 451 | break; |
| 439 | } | 452 | } |
| 440 | case NodeTypeUse: | 453 | case NodeTypeUse: |
| ... | @@ -621,7 +634,9 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i | ... | @@ -621,7 +634,9 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i |
| 621 | TypeTableEntry *return_type; | 634 | TypeTableEntry *return_type; |
| 622 | 635 | ||
| 623 | if (struct_type->id == TypeTableEntryIdStruct) { | 636 | if (struct_type->id == TypeTableEntryIdStruct) { |
| 637 | assert(node->codegen_node); | ||
| 624 | FieldAccessNode *codegen_field_access = &node->codegen_node->data.field_access_node; | 638 | FieldAccessNode *codegen_field_access = &node->codegen_node->data.field_access_node; |
| 639 | assert(codegen_field_access); | ||
| 625 | 640 | ||
| 626 | Buf *field_name = &node->data.field_access_expr.field_name; | 641 | Buf *field_name = &node->data.field_access_expr.field_name; |
| 627 | 642 | ||
| ... | @@ -847,6 +862,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, | ... | @@ -847,6 +862,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, |
| 847 | } else if (lhs_node->type == NodeTypeArrayAccessExpr) { | 862 | } else if (lhs_node->type == NodeTypeArrayAccessExpr) { |
| 848 | expected_rhs_type = analyze_array_access_expr(g, import, context, lhs_node); | 863 | expected_rhs_type = analyze_array_access_expr(g, import, context, lhs_node); |
| 849 | } else if (lhs_node->type == NodeTypeFieldAccessExpr) { | 864 | } else if (lhs_node->type == NodeTypeFieldAccessExpr) { |
| 865 | alloc_codegen_node(lhs_node); | ||
| 850 | expected_rhs_type = analyze_field_access_expr(g, import, context, lhs_node); | 866 | expected_rhs_type = analyze_field_access_expr(g, import, context, lhs_node); |
| 851 | } else { | 867 | } else { |
| 852 | add_node_error(g, lhs_node, | 868 | add_node_error(g, lhs_node, |
src/codegen.cpp+19-5| ... | @@ -194,6 +194,7 @@ static LLVMValueRef gen_array_ptr(CodeGen *g, AstNode *node) { | ... | @@ -194,6 +194,7 @@ static LLVMValueRef gen_array_ptr(CodeGen *g, AstNode *node) { |
| 194 | LLVMConstInt(LLVMInt32Type(), 0, false), | 194 | LLVMConstInt(LLVMInt32Type(), 0, false), |
| 195 | subscript_value | 195 | subscript_value |
| 196 | }; | 196 | }; |
| 197 | add_debug_source_node(g, node); | ||
| 197 | return LLVMBuildInBoundsGEP(g->builder, array_ref_value, indices, 2, ""); | 198 | return LLVMBuildInBoundsGEP(g->builder, array_ref_value, indices, 2, ""); |
| 198 | } | 199 | } |
| 199 | 200 | ||
| ... | @@ -206,6 +207,7 @@ static LLVMValueRef gen_field_val(CodeGen *g, AstNode *node) { | ... | @@ -206,6 +207,7 @@ static LLVMValueRef gen_field_val(CodeGen *g, AstNode *node) { |
| 206 | FieldAccessNode *codegen_field_access = &node->codegen_node->data.field_access_node; | 207 | FieldAccessNode *codegen_field_access = &node->codegen_node->data.field_access_node; |
| 207 | assert(codegen_field_access->field_index >= 0); | 208 | assert(codegen_field_access->field_index >= 0); |
| 208 | 209 | ||
| 210 | add_debug_source_node(g, node); | ||
| 209 | return LLVMBuildExtractValue(g->builder, struct_val, codegen_field_access->field_index, ""); | 211 | return LLVMBuildExtractValue(g->builder, struct_val, codegen_field_access->field_index, ""); |
| 210 | } | 212 | } |
| 211 | 213 | ||
| ... | @@ -221,11 +223,7 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node) { | ... | @@ -221,11 +223,7 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node) { |
| 221 | 223 | ||
| 222 | assert(codegen_field_access->field_index >= 0); | 224 | assert(codegen_field_access->field_index >= 0); |
| 223 | 225 | ||
| 224 | LLVMValueRef indices[] = { | 226 | return LLVMBuildStructGEP(g->builder, struct_ptr, codegen_field_access->field_index, ""); |
| 225 | LLVMConstInt(LLVMInt32Type(), 0, false), | ||
| 226 | LLVMConstInt(LLVMInt32Type(), codegen_field_access->field_index, false) | ||
| 227 | }; | ||
| 228 | return LLVMBuildStructGEP(g->builder, struct_ptr, indices, 2, ""); | ||
| 229 | } | 227 | } |
| 230 | */ | 228 | */ |
| 231 | 229 | ||
| ... | @@ -233,6 +231,7 @@ static LLVMValueRef gen_array_access_expr(CodeGen *g, AstNode *node) { | ... | @@ -233,6 +231,7 @@ static LLVMValueRef gen_array_access_expr(CodeGen *g, AstNode *node) { |
| 233 | assert(node->type == NodeTypeArrayAccessExpr); | 231 | assert(node->type == NodeTypeArrayAccessExpr); |
| 234 | 232 | ||
| 235 | LLVMValueRef ptr = gen_array_ptr(g, node); | 233 | LLVMValueRef ptr = gen_array_ptr(g, node); |
| 234 | add_debug_source_node(g, node); | ||
| 236 | return LLVMBuildLoad(g->builder, ptr, ""); | 235 | return LLVMBuildLoad(g->builder, ptr, ""); |
| 237 | } | 236 | } |
| 238 | 237 | ||
| ... | @@ -564,6 +563,21 @@ static LLVMValueRef gen_assign_expr(CodeGen *g, AstNode *node) { | ... | @@ -564,6 +563,21 @@ static LLVMValueRef gen_assign_expr(CodeGen *g, AstNode *node) { |
| 564 | LLVMValueRef value = gen_expr(g, node->data.bin_op_expr.op2); | 563 | LLVMValueRef value = gen_expr(g, node->data.bin_op_expr.op2); |
| 565 | add_debug_source_node(g, node); | 564 | add_debug_source_node(g, node); |
| 566 | return LLVMBuildStore(g->builder, value, ptr); | 565 | return LLVMBuildStore(g->builder, value, ptr); |
| 566 | } else if (lhs_node->type == NodeTypeFieldAccessExpr) { | ||
| 567 | /* | ||
| 568 | LLVMValueRef ptr = gen_field_ptr(g, lhs_node); | ||
| 569 | LLVMValueRef value = gen_expr(g, node->data.bin_op_expr.op2); | ||
| 570 | add_debug_source_node(g, node); | ||
| 571 | return LLVMBuildStore(g->builder, value, ptr); | ||
| 572 | */ | ||
| 573 | LLVMValueRef struct_val = gen_expr(g, lhs_node->data.field_access_expr.struct_expr); | ||
| 574 | assert(struct_val); | ||
| 575 | FieldAccessNode *codegen_field_access = &lhs_node->codegen_node->data.field_access_node; | ||
| 576 | assert(codegen_field_access->field_index >= 0); | ||
| 577 | |||
| 578 | LLVMValueRef value = gen_expr(g, node->data.bin_op_expr.op2); | ||
| 579 | add_debug_source_node(g, node); | ||
| 580 | return LLVMBuildInsertValue(g->builder, struct_val, value, codegen_field_access->field_index, ""); | ||
| 567 | } else { | 581 | } else { |
| 568 | zig_panic("bad assign target"); | 582 | zig_panic("bad assign target"); |
| 569 | } | 583 | } |