aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2015-11-24 23:44:41 -0700
committerAndrew Kelley <superjoe30@gmail.com>2015-11-24 23:44:41 -0700
commit09f68c7c339075183c67c56149620c6970b6842a (patch)
tree55afa659954e143035792d44bf4edf992d26fd18 /src/codegen.cpp
parentafac1a0123cb574e92fbc37e99e6778c51b46683 (diff)
downloadzig-09f68c7c339075183c67c56149620c6970b6842a.tar.gz
zig-09f68c7c339075183c67c56149620c6970b6842a.zip
support linker directives
now you can depend on libc in zig language instead of it being hardcoded in the compiler.
Diffstat (limited to 'src/codegen.cpp')
-rw-r--r--src/codegen.cpp28
1 files changed, 27 insertions, 1 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 5cd8236260..3df9ed876c 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -56,6 +56,7 @@ struct CodeGen {
HashMap<Buf *, FnTableEntry *, buf_hash, buf_eql_buf> fn_table;
HashMap<Buf *, LLVMValueRef, buf_hash, buf_eql_buf> str_table;
HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> type_table;
+ HashMap<Buf *, bool, buf_hash, buf_eql_buf> link_table;
TypeTableEntry *invalid_type_entry;
LLVMTargetDataRef target_data_ref;
unsigned pointer_size_bytes;
@@ -86,6 +87,7 @@ CodeGen *create_codegen(AstNode *root, Buf *in_full_path) {
g->fn_table.init(32);
g->str_table.init(32);
g->type_table.init(32);
+ g->link_table.init(32);
g->is_static = false;
g->build_type = CodeGenBuildTypeDebug;
g->strip_debug_symbols = false;
@@ -198,6 +200,18 @@ static void analyze_node(CodeGen *g, AstNode *node) {
}
break;
case NodeTypeExternBlock:
+ for (int i = 0; i < node->data.extern_block.directives->length; i += 1) {
+ AstNode *directive_node = node->data.extern_block.directives->at(i);
+ Buf *name = &directive_node->data.directive.name;
+ Buf *param = &directive_node->data.directive.param;
+ if (buf_eql_str(name, "link")) {
+ g->link_table.put(param, true);
+ } else {
+ add_node_error(g, node,
+ buf_sprintf("invalid directive: '%s'", buf_ptr(name)));
+ }
+ }
+
for (int fn_decl_i = 0; fn_decl_i < node->data.extern_block.fn_decls.length; fn_decl_i += 1) {
AstNode *fn_decl = node->data.extern_block.fn_decls.at(fn_decl_i);
analyze_node(g, fn_decl);
@@ -306,6 +320,8 @@ static void analyze_node(CodeGen *g, AstNode *node) {
analyze_node(g, child);
}
break;
+ case NodeTypeDirective:
+ break;
}
}
@@ -639,6 +655,16 @@ void code_gen_link(CodeGen *g, const char *out_file) {
args.append("-o");
args.append(out_file);
args.append((const char *)buf_ptr(&out_file_o));
- args.append("-lc");
+
+ auto it = g->link_table.entry_iterator();
+ for (;;) {
+ auto *entry = it.next();
+ if (!entry)
+ break;
+
+ Buf *arg = buf_sprintf("-l%s", buf_ptr(entry->key));
+ args.append(buf_ptr(arg));
+ }
+
os_spawn_process("ld", args, false);
}