don't mangle symbols with underscores

closes #275
This commit is contained in:
Andrew Kelley 2017-03-23 18:28:10 -04:00
parent d6856859d3
commit fd634f3db3
4 changed files with 46 additions and 8 deletions

View File

@ -1293,6 +1293,7 @@ struct CodeGen {
HashMap<Scope *, IrInstruction *, fn_eval_hash, fn_eval_eql> memoized_fn_eval_table;
HashMap<ZigLLVMFnKey, LLVMValueRef, zig_llvm_fn_key_hash, zig_llvm_fn_key_eql> llvm_fn_table;
HashMap<Buf *, ConstExprValue *, buf_hash, buf_eql_buf> compile_vars;
HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> external_symbol_names;
ZigList<ImportTableEntry *> import_queue;
size_t import_queue_index;

View File

@ -1904,6 +1904,16 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
g->resolve_queue.append(tld);
}
if (tld->visib_mod == VisibModExport) {
auto entry = g->external_symbol_names.put_unique(tld->name, tld);
if (entry) {
Tld *other_tld = entry->value;
ErrorMsg *msg = add_node_error(g, tld->source_node,
buf_sprintf("exported symbol collision: '%s'", buf_ptr(tld->name)));
add_error_note(g, msg, other_tld->source_node, buf_sprintf("other symbol is here"));
}
}
auto entry = decls_scope->decl_table.put_unique(tld->name, tld);
if (entry) {
Tld *other_tld = entry->value;

View File

@ -67,6 +67,7 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {
g->llvm_fn_table.init(16);
g->memoized_fn_eval_table.init(16);
g->compile_vars.init(16);
g->external_symbol_names.init(8);
g->is_release_build = false;
g->is_test_build = false;
g->want_h_file = true;
@ -260,16 +261,25 @@ static void addLLVMArgAttr(LLVMValueRef arg_val, unsigned param_index, const cha
return addLLVMAttr(arg_val, param_index + 1, attr_name);
}
static Buf *get_mangled_name(CodeGen *g, Buf *original_name, bool external_linkage) {
if (external_linkage || g->external_symbol_names.maybe_get(original_name) == nullptr) {
return original_name;
}
int n = 0;
for (;; n += 1) {
Buf *new_name = buf_sprintf("%s.%d", buf_ptr(original_name), n);
if (g->external_symbol_names.maybe_get(new_name) == nullptr) {
return new_name;
}
}
}
static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
if (fn_table_entry->llvm_value)
return fn_table_entry->llvm_value;
Buf *symbol_name;
if (!fn_table_entry->internal_linkage) {
symbol_name = &fn_table_entry->symbol_name;
} else {
symbol_name = buf_sprintf("_%s", buf_ptr(&fn_table_entry->symbol_name));
}
Buf *symbol_name = get_mangled_name(g, &fn_table_entry->symbol_name, !fn_table_entry->internal_linkage);
TypeTableEntry *fn_type = fn_table_entry->type_entry;
LLVMTypeRef fn_llvm_type = fn_type->data.fn.raw_type_ref;
@ -3288,7 +3298,7 @@ static void do_code_gen(CodeGen *g) {
LLVMSetLinkage(global_value, LLVMExternalLinkage);
} else {
render_const_val(g, var->value);
render_const_val_global(g, var->value, buf_ptr(&var->name));
render_const_val_global(g, var->value, buf_ptr(get_mangled_name(g, &var->name, false)));
global_value = var->value->llvm_global;
if (var->linkage == VarLinkageExport) {

View File

@ -1631,7 +1631,7 @@ const foo = @import("foo.zig");
export fn callPrivFunction() {
foo.privateFunction();
}
)SOURCE", 2,
)SOURCE", 2,
".tmp_source.zig:5:8: error: 'privateFunction' is private",
"foo.zig:2:1: note: declared here");
@ -1828,6 +1828,23 @@ fn ptrEql(a: &[]const u8, b: &[]const u8) -> bool {
export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
)SOURCE", 1, ".tmp_source.zig:5:19: error: expected type '&[]const u8', found '&const []const u8'");
{
TestCase *tc = add_compile_fail_case("export collision", R"SOURCE(
const foo = @import("foo.zig");
export fn bar() -> usize {
return foo.baz;
}
)SOURCE", 2,
"foo.zig:2:8: error: exported symbol collision: 'bar'",
".tmp_source.zig:4:8: note: other symbol is here");
add_source_file(tc, "foo.zig", R"SOURCE(
export fn bar() {}
pub const baz = 1234;
)SOURCE");
}
}
//////////////////////////////////////////////////////////////////////////////