aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen.cpp')
-rw-r--r--src/codegen.cpp54
1 files changed, 51 insertions, 3 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp
index f1aaf84392..0577e98c59 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -1,11 +1,16 @@
+/*
+ * Copyright (c) 2015 Andrew Kelley
+ *
+ * This file is part of zig, which is MIT licensed.
+ * See http://opensource.org/licenses/MIT
+ */
+
#include "codegen.hpp"
#include "hash_map.hpp"
+#include "zig_llvm.hpp"
#include <stdio.h>
-#include <llvm-c/Core.h>
-#include <llvm-c/Analysis.h>
-
struct FnTableEntry {
LLVMValueRef fn_value;
AstNode *proto_node;
@@ -49,6 +54,7 @@ static void add_node_error(CodeGen *g, AstNode *node, Buf *msg) {
static LLVMTypeRef to_llvm_type(AstNode *type_node) {
assert(type_node->type == NodeTypeType);
assert(type_node->codegen_node);
+ assert(type_node->codegen_node->data.type_ref);
return type_node->codegen_node->data.type_ref;
}
@@ -134,9 +140,12 @@ static void analyze_node(CodeGen *g, AstNode *node) {
node->codegen_node->data.type_ref = LLVMInt8Type();
} else if (buf_eql_str(name, "i32")) {
node->codegen_node->data.type_ref = LLVMInt32Type();
+ } else if (buf_eql_str(name, "void")) {
+ node->codegen_node->data.type_ref = LLVMVoidType();
} else {
add_node_error(g, node,
buf_sprintf("invalid type name: '%s'", buf_ptr(name)));
+ node->codegen_node->data.type_ref = LLVMInt8Type();
}
break;
}
@@ -339,3 +348,42 @@ void code_gen(CodeGen *g) {
ZigList<ErrorMsg> *codegen_error_messages(CodeGen *g) {
return &g->errors;
}
+
+
+void code_gen_link(CodeGen *g, bool is_static, const char *out_file) {
+ LLVMInitializeAllTargets();
+ LLVMInitializeAllTargetMCs();
+ LLVMInitializeAllAsmPrinters();
+ LLVMInitializeAllAsmParsers();
+ LLVMInitializeNativeTarget();
+
+
+ LLVMPassRegistryRef registry = LLVMGetGlobalPassRegistry();
+ LLVMInitializeCore(registry);
+ LLVMInitializeCodeGen(registry);
+ LLVMZigInitializeLoopStrengthReducePass(registry);
+ LLVMZigInitializeLowerIntrinsicsPass(registry);
+ LLVMZigInitializeUnreachableBlockElimPass(registry);
+
+ char *native_triple = LLVMGetDefaultTargetTriple();
+
+ LLVMTargetRef target_ref;
+ char *err_msg = nullptr;
+ if (LLVMGetTargetFromTriple(native_triple, &target_ref, &err_msg)) {
+ zig_panic("unable to get target from triple: %s", err_msg);
+ }
+
+ char *native_cpu = LLVMZigGetHostCPUName();
+ char *native_features = LLVMZigGetNativeFeatures();
+
+ LLVMCodeGenOptLevel opt_level = LLVMCodeGenLevelNone;
+
+ LLVMRelocMode reloc_mode = is_static ? LLVMRelocStatic : LLVMRelocPIC;
+
+ LLVMTargetMachineRef target_machine = LLVMCreateTargetMachine(target_ref, native_triple,
+ native_cpu, native_features, opt_level, reloc_mode, LLVMCodeModelDefault);
+
+ if (LLVMTargetMachineEmitToFile(target_machine, g->mod, strdup(out_file), LLVMObjectFile, &err_msg)) {
+ zig_panic("unable to write object file: %s", err_msg);
+ }
+}