diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2015-12-15 17:11:44 -0700 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2015-12-15 17:11:57 -0700 |
| commit | 423ee0689be4f93b2613a5e42e7411887a9a46ad (patch) | |
| tree | 3e5e1c02c7e108968e699eb5d7c4844b1c9cd9a4 /src/codegen.cpp | |
| parent | 8a570c458bcf62bc3d882f8d253f75ec6d3fd719 (diff) | |
| download | zig-423ee0689be4f93b2613a5e42e7411887a9a46ad.tar.gz zig-423ee0689be4f93b2613a5e42e7411887a9a46ad.zip | |
add implicit casting support
Diffstat (limited to 'src/codegen.cpp')
| -rw-r--r-- | src/codegen.cpp | 60 |
1 files changed, 49 insertions, 11 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index b0a7eae2c8..f81d07faa6 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -274,16 +274,9 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { zig_unreachable(); } -static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) { - assert(node->type == NodeTypeCastExpr); - - LLVMValueRef expr_val = gen_expr(g, node->data.cast_expr.expr); - - TypeTableEntry *actual_type = get_expr_type(node->data.cast_expr.expr); - TypeTableEntry *wanted_type = get_expr_type(node); - - CastNode *cast_node = &node->codegen_node->data.cast_node; - +static LLVMValueRef gen_bare_cast(CodeGen *g, AstNode *node, LLVMValueRef expr_val, + TypeTableEntry *actual_type, TypeTableEntry *wanted_type, CastNode *cast_node) +{ switch (cast_node->op) { case CastOpNothing: return expr_val; @@ -327,6 +320,20 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) { zig_unreachable(); } +static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) { + assert(node->type == NodeTypeCastExpr); + + LLVMValueRef expr_val = gen_expr(g, node->data.cast_expr.expr); + + TypeTableEntry *actual_type = get_expr_type(node->data.cast_expr.expr); + TypeTableEntry *wanted_type = get_expr_type(node); + + CastNode *cast_node = &node->codegen_node->data.cast_node; + + return gen_bare_cast(g, node, expr_val, actual_type, wanted_type, cast_node); + +} + static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, LLVMValueRef val1, LLVMValueRef val2, TypeTableEntry *op1_type, TypeTableEntry *op2_type, @@ -871,7 +878,7 @@ static LLVMValueRef gen_asm_expr(CodeGen *g, AstNode *node) { return LLVMBuildCall(g->builder, asm_fn, param_values, input_and_output_count, ""); } -static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { +static LLVMValueRef gen_expr_no_cast(CodeGen *g, AstNode *node) { switch (node->type) { case NodeTypeBinOpExpr: return gen_bin_op_expr(g, node); @@ -1022,6 +1029,22 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { zig_unreachable(); } +static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { + LLVMValueRef val = gen_expr_no_cast(g, node); + + if (node->type == NodeTypeVoid) { + return val; + } + + assert(node->codegen_node); + + TypeTableEntry *actual_type = node->codegen_node->expr_node.type_entry; + TypeTableEntry *cast_type = node->codegen_node->expr_node.cast_type; + + return cast_type ? gen_bare_cast(g, node, val, actual_type, cast_type, + &node->codegen_node->expr_node.implicit_cast) : val; +} + static void build_label_blocks(CodeGen *g, AstNode *block_node) { assert(block_node->type == NodeTypeBlock); for (int i = 0; i < block_node->data.block.statements.length; i += 1) { @@ -1324,6 +1347,19 @@ static void define_builtin_types(CodeGen *g) { g->builtin_types.entry_c_string_literal = get_pointer_to_type(g, g->builtin_types.entry_u8, true); { TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); + entry->type_ref = LLVMInt8Type(); + buf_init_from_str(&entry->name, "i8"); + entry->size_in_bits = 8; + entry->align_in_bits = 8; + entry->data.integral.is_signed = true; + entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), + entry->size_in_bits, entry->align_in_bits, + LLVMZigEncoding_DW_ATE_signed()); + g->type_table.put(&entry->name, entry); + g->builtin_types.entry_i8 = entry; + } + { + TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); entry->type_ref = LLVMInt32Type(); buf_init_from_str(&entry->name, "i32"); entry->size_in_bits = 32; @@ -1951,6 +1987,8 @@ void codegen_link(CodeGen *g, const char *out_file) { fprintf(stderr, "ld failed with return code %d\n", return_code); fprintf(stderr, "%s\n", buf_ptr(&ld_stderr)); exit(1); + } else if (buf_len(&ld_stderr)) { + fprintf(stderr, "%s\n", buf_ptr(&ld_stderr)); } if (g->out_type == OutTypeLib) { |
