From 38f12adbda5d3b0114232fdccdbcc0b4179f9115 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 12 Dec 2015 02:34:09 -0700 Subject: [PATCH] progress on struct support --- example/structs/structs.zig | 4 +++- src/analyze.cpp | 20 ++++++++++++++++++-- src/codegen.cpp | 24 +++++++++++++++++++----- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/example/structs/structs.zig b/example/structs/structs.zig index a5d52b6b1..b274184b8 100644 --- a/example/structs/structs.zig +++ b/example/structs/structs.zig @@ -2,6 +2,8 @@ export executable "structs"; use "std.zig"; +// Note: this example is not working because codegen is confused about +// how byvalue structs which are in memory on the stack work export fn main(argc : isize, argv : *mut *mut u8, env : *mut *mut u8) -> i32 { let mut foo : Foo; @@ -22,6 +24,6 @@ struct Foo { fn test_foo(foo : Foo) { if foo.b { - print_str("OK"); + print_str("OK" as string); } } diff --git a/src/analyze.cpp b/src/analyze.cpp index 923e340c0..89e5e109b 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -422,6 +422,9 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import, type_entry->data.structure.fields = allocate(field_count); LLVMTypeRef *element_types = allocate(field_count); + LLVMZigDIType **di_element_types = allocate(field_count); + + uint64_t total_size_in_bits = 0; for (int i = 0; i < field_count; i += 1) { AstNode *field_node = node->data.struct_decl.fields.at(i); @@ -429,12 +432,22 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import, type_struct_field->name = &field_node->data.struct_field.name; type_struct_field->type_entry = resolve_type(g, field_node->data.struct_field.type); + total_size_in_bits = type_struct_field->type_entry->size_in_bits; + di_element_types[i] = type_struct_field->type_entry->di_type; + element_types[i] = type_struct_field->type_entry->type_ref; } - // TODO align_in_bits and size_in_bits - // TODO set up ditype for the struct LLVMStructSetBody(type_entry->type_ref, element_types, field_count, false); + // TODO re-evaluate this align in bits and size in bits + type_entry->align_in_bits = 0; + type_entry->size_in_bits = total_size_in_bits; + type_entry->di_type = LLVMZigCreateDebugStructType(g->dbuilder, + LLVMZigFileToScope(import->di_file), + buf_ptr(&node->data.struct_decl.name), + import->di_file, node->line + 1, type_entry->size_in_bits, type_entry->align_in_bits, 0, + nullptr, di_element_types, field_count, 0, nullptr, ""); + break; } case NodeTypeUse: @@ -621,7 +634,9 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i TypeTableEntry *return_type; if (struct_type->id == TypeTableEntryIdStruct) { + assert(node->codegen_node); FieldAccessNode *codegen_field_access = &node->codegen_node->data.field_access_node; + assert(codegen_field_access); Buf *field_name = &node->data.field_access_expr.field_name; @@ -847,6 +862,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, } else if (lhs_node->type == NodeTypeArrayAccessExpr) { expected_rhs_type = analyze_array_access_expr(g, import, context, lhs_node); } else if (lhs_node->type == NodeTypeFieldAccessExpr) { + alloc_codegen_node(lhs_node); expected_rhs_type = analyze_field_access_expr(g, import, context, lhs_node); } else { add_node_error(g, lhs_node, diff --git a/src/codegen.cpp b/src/codegen.cpp index c43d3f997..7329f53d9 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -194,6 +194,7 @@ static LLVMValueRef gen_array_ptr(CodeGen *g, AstNode *node) { LLVMConstInt(LLVMInt32Type(), 0, false), subscript_value }; + add_debug_source_node(g, node); return LLVMBuildInBoundsGEP(g->builder, array_ref_value, indices, 2, ""); } @@ -206,6 +207,7 @@ static LLVMValueRef gen_field_val(CodeGen *g, AstNode *node) { FieldAccessNode *codegen_field_access = &node->codegen_node->data.field_access_node; assert(codegen_field_access->field_index >= 0); + add_debug_source_node(g, node); return LLVMBuildExtractValue(g->builder, struct_val, codegen_field_access->field_index, ""); } @@ -221,11 +223,7 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node) { assert(codegen_field_access->field_index >= 0); - LLVMValueRef indices[] = { - LLVMConstInt(LLVMInt32Type(), 0, false), - LLVMConstInt(LLVMInt32Type(), codegen_field_access->field_index, false) - }; - return LLVMBuildStructGEP(g->builder, struct_ptr, indices, 2, ""); + return LLVMBuildStructGEP(g->builder, struct_ptr, codegen_field_access->field_index, ""); } */ @@ -233,6 +231,7 @@ static LLVMValueRef gen_array_access_expr(CodeGen *g, AstNode *node) { assert(node->type == NodeTypeArrayAccessExpr); LLVMValueRef ptr = gen_array_ptr(g, node); + add_debug_source_node(g, node); return LLVMBuildLoad(g->builder, ptr, ""); } @@ -564,6 +563,21 @@ static LLVMValueRef gen_assign_expr(CodeGen *g, AstNode *node) { LLVMValueRef value = gen_expr(g, node->data.bin_op_expr.op2); add_debug_source_node(g, node); return LLVMBuildStore(g->builder, value, ptr); + } else if (lhs_node->type == NodeTypeFieldAccessExpr) { + /* + LLVMValueRef ptr = gen_field_ptr(g, lhs_node); + LLVMValueRef value = gen_expr(g, node->data.bin_op_expr.op2); + add_debug_source_node(g, node); + return LLVMBuildStore(g->builder, value, ptr); + */ + LLVMValueRef struct_val = gen_expr(g, lhs_node->data.field_access_expr.struct_expr); + assert(struct_val); + FieldAccessNode *codegen_field_access = &lhs_node->codegen_node->data.field_access_node; + assert(codegen_field_access->field_index >= 0); + + LLVMValueRef value = gen_expr(g, node->data.bin_op_expr.op2); + add_debug_source_node(g, node); + return LLVMBuildInsertValue(g->builder, struct_val, value, codegen_field_access->field_index, ""); } else { zig_panic("bad assign target"); }