diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2015-12-12 02:05:08 -0700 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2015-12-12 02:05:08 -0700 |
| commit | ac630d354d51488d895bc14e26a069ae954ac5c6 (patch) | |
| tree | ff99cc11334991a76d7ab0837112f00b8b1b0c3c /src/codegen.cpp | |
| parent | a10277bd949d47370e427d4457d93e907de9a6f7 (diff) | |
| download | zig-ac630d354d51488d895bc14e26a069ae954ac5c6.tar.gz zig-ac630d354d51488d895bc14e26a069ae954ac5c6.zip | |
std: print_str no longer requires length argument
add explicit casting support from array to string
Diffstat (limited to 'src/codegen.cpp')
| -rw-r--r-- | src/codegen.cpp | 86 |
1 files changed, 63 insertions, 23 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index 368e85edb1..c43d3f997d 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -197,6 +197,38 @@ static LLVMValueRef gen_array_ptr(CodeGen *g, AstNode *node) { return LLVMBuildInBoundsGEP(g->builder, array_ref_value, indices, 2, ""); } +static LLVMValueRef gen_field_val(CodeGen *g, AstNode *node) { + assert(node->type == NodeTypeFieldAccessExpr); + + LLVMValueRef struct_val = gen_expr(g, node->data.field_access_expr.struct_expr); + assert(struct_val); + + FieldAccessNode *codegen_field_access = &node->codegen_node->data.field_access_node; + assert(codegen_field_access->field_index >= 0); + + return LLVMBuildExtractValue(g->builder, struct_val, codegen_field_access->field_index, ""); +} + +/* +static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node) { + assert(node->type == NodeTypeFieldAccessExpr); + + LLVMValueRef struct_ptr = gen_expr(g, node->data.field_access_expr.struct_expr); + + assert(struct_ptr); + + FieldAccessNode *codegen_field_access = &node->codegen_node->data.field_access_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, ""); +} +*/ + static LLVMValueRef gen_array_access_expr(CodeGen *g, AstNode *node) { assert(node->type == NodeTypeArrayAccessExpr); @@ -208,12 +240,8 @@ static LLVMValueRef gen_field_access_expr(CodeGen *g, AstNode *node) { assert(node->type == NodeTypeFieldAccessExpr); TypeTableEntry *struct_type = get_expr_type(node->data.field_access_expr.struct_expr); - LLVMValueRef struct_ptr = gen_expr(g, node->data.field_access_expr.struct_expr); Buf *name = &node->data.field_access_expr.field_name; - // TODO add struct support - (void)struct_ptr; - if (struct_type->id == TypeTableEntryIdArray) { if (buf_eql_str(name, "len")) { return LLVMConstInt(g->builtin_types.entry_usize->type_ref, @@ -221,6 +249,12 @@ static LLVMValueRef gen_field_access_expr(CodeGen *g, AstNode *node) { } else { zig_panic("gen_field_access_expr bad array field"); } + } else if (struct_type->id == TypeTableEntryIdStruct) { + /* + LLVMValueRef ptr = gen_field_ptr(g, node); + return LLVMBuildLoad(g->builder, ptr, ""); + */ + return gen_field_val(g, node); } else { zig_panic("gen_field_access_expr bad struct type"); } @@ -259,30 +293,36 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) { TypeTableEntry *actual_type = get_expr_type(node->data.cast_expr.expr); TypeTableEntry *wanted_type = get_expr_type(node); - // this asserts are here only because no other casting codegen is supported currently - assert(wanted_type == g->builtin_types.entry_isize); - - if (wanted_type->id == TypeTableEntryIdPointer) { - return LLVMBuildIntToPtr(g->builder, expr_val, wanted_type->type_ref, ""); - } else if (wanted_type->id == TypeTableEntryIdInt) { - if (actual_type->size_in_bits == wanted_type->size_in_bits) { - if (actual_type->id == TypeTableEntryIdPointer) { - return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, ""); + CastNode *cast_node = &node->codegen_node->data.cast_node; + + switch (cast_node->op) { + case CastOpPtrToInt: + return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, ""); + case CastOpIntWidenOrShorten: + if (actual_type->size_in_bits == wanted_type->size_in_bits) { + return expr_val; + } else if (actual_type->size_in_bits < wanted_type->size_in_bits) { + if (actual_type->data.integral.is_signed && wanted_type->data.integral.is_signed) { + return LLVMBuildSExt(g->builder, expr_val, wanted_type->type_ref, ""); + } else { + zig_panic("TODO gen_cast_expr sign mismatch"); + } } else { zig_panic("TODO gen_cast_expr"); } - } else if (actual_type->size_in_bits < wanted_type->size_in_bits) { - if (actual_type->data.integral.is_signed && wanted_type->data.integral.is_signed) { - return LLVMBuildSExt(g->builder, expr_val, wanted_type->type_ref, ""); - } else { - zig_panic("TODO gen_cast_expr sign mismatch"); + case CastOpArrayToString: + { + LLVMValueRef struct_vals[] = { + expr_val, + LLVMConstInt(g->builtin_types.entry_usize->type_ref, actual_type->data.array.len, false) + }; + unsigned field_count = g->builtin_types.entry_string->data.structure.field_count; + assert(field_count == 2); + return LLVMConstNamedStruct(g->builtin_types.entry_string->type_ref, + struct_vals, field_count); } - } else { - zig_panic("TODO gen_cast_expr"); - } - } else { - zig_panic("TODO gen_cast_expr"); } + zig_unreachable(); } static LLVMValueRef gen_arithmetic_bin_op_expr(CodeGen *g, AstNode *node) { |
