progress on struct support
parent
ac630d354d
commit
38f12adbda
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -422,6 +422,9 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import,
|
|||
type_entry->data.structure.fields = allocate<TypeStructField>(field_count);
|
||||
|
||||
LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count);
|
||||
LLVMZigDIType **di_element_types = allocate<LLVMZigDIType*>(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,
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue