add implicit casting support

This commit is contained in:
Andrew Kelley
2015-12-15 17:11:44 -07:00
parent 8a570c458b
commit 423ee0689b
5 changed files with 200 additions and 84 deletions

View File

@@ -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) {
@@ -1322,6 +1345,19 @@ static void define_builtin_types(CodeGen *g) {
g->builtin_types.entry_u64 = entry;
}
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();
@@ -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) {