authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-12-12 02:34:09-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-12-12 02:34:09-07:00
log38f12adbda5d3b0114232fdccdbcc0b4179f9115
tree5016bcd2cccea018738aa30c9bb7e91b2aaa9c2b
parentac630d354d51488d895bc14e26a069ae954ac5c6

progress on struct support


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";
22
3use "std.zig";3use "std.zig";
44
5// Note: this example is not working because codegen is confused about
6// how byvalue structs which are in memory on the stack work
5export fn main(argc : isize, argv : *mut *mut u8, env : *mut *mut u8) -> i32 {7export fn main(argc : isize, argv : *mut *mut u8, env : *mut *mut u8) -> i32 {
6 let mut foo : Foo;8 let mut foo : Foo;
79
...@@ -22,6 +24,6 @@ struct Foo {...@@ -22,6 +24,6 @@ struct Foo {
2224
23fn test_foo(foo : Foo) {25fn 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);
423423
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;
425428
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);
431434
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);
437441
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;
622635
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);
625640
626 Buf *field_name = &node->data.field_access_expr.field_name;641 Buf *field_name = &node->data.field_access_expr.field_name;
627642
...@@ -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_value195 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}
199200
...@@ -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);
208209
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}
211213
...@@ -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) {
221223
222 assert(codegen_field_access->field_index >= 0);224 assert(codegen_field_access->field_index >= 0);
223225
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*/
231229
...@@ -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);
234232
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}
238237
...@@ -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 }