authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-03-23 18:28:10-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-03-23 18:28:10-04:00
logfd634f3db35791ea904e82a525e4f49f4c5b67a8
treeb6e44cde3540f2ecf26724e830a8110020546d25
parentd6856859d3082d9b66aac7c25ceb2abcd13e2f7c

don't mangle symbols with underscores

closes #275

4 files changed, 46 insertions(+), 8 deletions(-)

src/all_types.hpp+1
......@@ -1293,6 +1293,7 @@ struct CodeGen {
12931293 HashMap<Scope *, IrInstruction *, fn_eval_hash, fn_eval_eql> memoized_fn_eval_table;
12941294 HashMap<ZigLLVMFnKey, LLVMValueRef, zig_llvm_fn_key_hash, zig_llvm_fn_key_eql> llvm_fn_table;
12951295 HashMap<Buf *, ConstExprValue *, buf_hash, buf_eql_buf> compile_vars;
1296 HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> external_symbol_names;
12961297
12971298 ZigList<ImportTableEntry *> import_queue;
12981299 size_t import_queue_index;
src/analyze.cpp+10
......@@ -1904,6 +1904,16 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
19041904 g->resolve_queue.append(tld);
19051905 }
19061906
1907 if (tld->visib_mod == VisibModExport) {
1908 auto entry = g->external_symbol_names.put_unique(tld->name, tld);
1909 if (entry) {
1910 Tld *other_tld = entry->value;
1911 ErrorMsg *msg = add_node_error(g, tld->source_node,
1912 buf_sprintf("exported symbol collision: '%s'", buf_ptr(tld->name)));
1913 add_error_note(g, msg, other_tld->source_node, buf_sprintf("other symbol is here"));
1914 }
1915 }
1916
19071917 auto entry = decls_scope->decl_table.put_unique(tld->name, tld);
19081918 if (entry) {
19091919 Tld *other_tld = entry->value;
src/codegen.cpp+17-7
......@@ -67,6 +67,7 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {
6767 g->llvm_fn_table.init(16);
6868 g->memoized_fn_eval_table.init(16);
6969 g->compile_vars.init(16);
70 g->external_symbol_names.init(8);
7071 g->is_release_build = false;
7172 g->is_test_build = false;
7273 g->want_h_file = true;
......@@ -260,16 +261,25 @@ static void addLLVMArgAttr(LLVMValueRef arg_val, unsigned param_index, const cha
260261 return addLLVMAttr(arg_val, param_index + 1, attr_name);
261262}
262263
264static Buf *get_mangled_name(CodeGen *g, Buf *original_name, bool external_linkage) {
265 if (external_linkage || g->external_symbol_names.maybe_get(original_name) == nullptr) {
266 return original_name;
267 }
268
269 int n = 0;
270 for (;; n += 1) {
271 Buf *new_name = buf_sprintf("%s.%d", buf_ptr(original_name), n);
272 if (g->external_symbol_names.maybe_get(new_name) == nullptr) {
273 return new_name;
274 }
275 }
276}
277
263278static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
264279 if (fn_table_entry->llvm_value)
265280 return fn_table_entry->llvm_value;
266281
267 Buf *symbol_name;
268 if (!fn_table_entry->internal_linkage) {
269 symbol_name = &fn_table_entry->symbol_name;
270 } else {
271 symbol_name = buf_sprintf("_%s", buf_ptr(&fn_table_entry->symbol_name));
272 }
282 Buf *symbol_name = get_mangled_name(g, &fn_table_entry->symbol_name, !fn_table_entry->internal_linkage);
273283
274284 TypeTableEntry *fn_type = fn_table_entry->type_entry;
275285 LLVMTypeRef fn_llvm_type = fn_type->data.fn.raw_type_ref;
......@@ -3288,7 +3298,7 @@ static void do_code_gen(CodeGen *g) {
32883298 LLVMSetLinkage(global_value, LLVMExternalLinkage);
32893299 } else {
32903300 render_const_val(g, var->value);
3291 render_const_val_global(g, var->value, buf_ptr(&var->name));
3301 render_const_val_global(g, var->value, buf_ptr(get_mangled_name(g, &var->name, false)));
32923302 global_value = var->value->llvm_global;
32933303
32943304 if (var->linkage == VarLinkageExport) {
test/run_tests.cpp+18-1
......@@ -1631,7 +1631,7 @@ const foo = @import("foo.zig");
16311631export fn callPrivFunction() {
16321632 foo.privateFunction();
16331633}
1634 )SOURCE", 2,
1634 )SOURCE", 2,
16351635 ".tmp_source.zig:5:8: error: 'privateFunction' is private",
16361636 "foo.zig:2:1: note: declared here");
16371637
......@@ -1828,6 +1828,23 @@ fn ptrEql(a: &[]const u8, b: &[]const u8) -> bool {
18281828
18291829export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
18301830 )SOURCE", 1, ".tmp_source.zig:5:19: error: expected type '&[]const u8', found '&const []const u8'");
1831
1832 {
1833 TestCase *tc = add_compile_fail_case("export collision", R"SOURCE(
1834const foo = @import("foo.zig");
1835
1836export fn bar() -> usize {
1837 return foo.baz;
1838}
1839 )SOURCE", 2,
1840 "foo.zig:2:8: error: exported symbol collision: 'bar'",
1841 ".tmp_source.zig:4:8: note: other symbol is here");
1842
1843 add_source_file(tc, "foo.zig", R"SOURCE(
1844export fn bar() {}
1845pub const baz = 1234;
1846 )SOURCE");
1847 }
18311848}
18321849
18331850//////////////////////////////////////////////////////////////////////////////