aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2015-12-12 02:05:08 -0700
committerAndrew Kelley <superjoe30@gmail.com>2015-12-12 02:05:08 -0700
commitac630d354d51488d895bc14e26a069ae954ac5c6 (patch)
treeff99cc11334991a76d7ab0837112f00b8b1b0c3c /src/codegen.cpp
parenta10277bd949d47370e427d4457d93e907de9a6f7 (diff)
downloadzig-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.cpp86
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) {