parent
763357c9c3
commit
557983e502
|
@ -1679,7 +1679,7 @@ struct CodeGen {
|
|||
HashMap<GenericFnTypeId *, ZigFn *, generic_fn_type_id_hash, generic_fn_type_id_eql> generic_table;
|
||||
HashMap<Scope *, ConstExprValue *, 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 *, AstNode *, buf_hash, buf_eql_buf> exported_symbol_names;
|
||||
HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> exported_symbol_names;
|
||||
HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> external_prototypes;
|
||||
HashMap<Buf *, ConstExprValue *, buf_hash, buf_eql_buf> string_literals_table;
|
||||
HashMap<const ZigType *, ConstExprValue *, type_ptr_hash, type_ptr_eql> type_info_cache;
|
||||
|
|
|
@ -3439,9 +3439,9 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
|
|||
if (is_export) {
|
||||
g->resolve_queue.append(tld);
|
||||
|
||||
auto entry = g->exported_symbol_names.put_unique(tld->name, tld->source_node);
|
||||
auto entry = g->exported_symbol_names.put_unique(tld->name, tld);
|
||||
if (entry) {
|
||||
AstNode *other_source_node = entry->value;
|
||||
AstNode *other_source_node = entry->value->source_node;
|
||||
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_source_node, buf_sprintf("other symbol here"));
|
||||
|
|
|
@ -478,10 +478,23 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {
|
|||
fn_table_entry->llvm_value = LLVMConstBitCast(existing_llvm_fn, LLVMPointerType(fn_llvm_type, 0));
|
||||
return fn_table_entry->llvm_value;
|
||||
} else {
|
||||
fn_table_entry->llvm_value = LLVMAddFunction(g->module, buf_ptr(symbol_name), fn_llvm_type);
|
||||
auto entry = g->exported_symbol_names.maybe_get(symbol_name);
|
||||
if (entry == nullptr) {
|
||||
fn_table_entry->llvm_value = LLVMAddFunction(g->module, buf_ptr(symbol_name), fn_llvm_type);
|
||||
} else {
|
||||
assert(entry->value->id == TldIdFn);
|
||||
TldFn *tld_fn = reinterpret_cast<TldFn *>(entry->value);
|
||||
tld_fn->fn_entry->llvm_value = LLVMAddFunction(g->module, buf_ptr(symbol_name),
|
||||
tld_fn->fn_entry->type_entry->data.fn.raw_type_ref);
|
||||
fn_table_entry->llvm_value = LLVMConstBitCast(tld_fn->fn_entry->llvm_value,
|
||||
LLVMPointerType(fn_llvm_type, 0));
|
||||
return fn_table_entry->llvm_value;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fn_table_entry->llvm_value = LLVMAddFunction(g->module, buf_ptr(symbol_name), fn_llvm_type);
|
||||
if (fn_table_entry->llvm_value == nullptr) {
|
||||
fn_table_entry->llvm_value = LLVMAddFunction(g->module, buf_ptr(symbol_name), fn_llvm_type);
|
||||
}
|
||||
|
||||
for (size_t i = 1; i < fn_table_entry->export_list.length; i += 1) {
|
||||
FnExport *fn_export = &fn_table_entry->export_list.items[i];
|
||||
|
|
14
src/ir.cpp
14
src/ir.cpp
|
@ -13279,12 +13279,21 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
|
|||
}
|
||||
}
|
||||
|
||||
auto entry = ira->codegen->exported_symbol_names.put_unique(symbol_name, instruction->base.source_node);
|
||||
// TODO: This function needs to be audited.
|
||||
// It's not clear how all the different types are supposed to be handled.
|
||||
// Need comprehensive tests for exporting one thing in one file and declaring an extern var
|
||||
// in another file.
|
||||
TldFn *tld_fn = allocate<TldFn>(1);
|
||||
tld_fn->base.id = TldIdFn;
|
||||
tld_fn->base.source_node = instruction->base.source_node;
|
||||
|
||||
auto entry = ira->codegen->exported_symbol_names.put_unique(symbol_name, &tld_fn->base);
|
||||
if (entry) {
|
||||
AstNode *other_export_node = entry->value;
|
||||
AstNode *other_export_node = entry->value->source_node;
|
||||
ErrorMsg *msg = ir_add_error(ira, &instruction->base,
|
||||
buf_sprintf("exported symbol collision: '%s'", buf_ptr(symbol_name)));
|
||||
add_error_note(ira->codegen, msg, other_export_node, buf_sprintf("other symbol is here"));
|
||||
return ira->codegen->invalid_instruction;
|
||||
}
|
||||
|
||||
bool want_var_export = false;
|
||||
|
@ -13295,6 +13304,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
|
|||
case ZigTypeIdFn: {
|
||||
assert(target->value.data.x_ptr.special == ConstPtrSpecialFunction);
|
||||
ZigFn *fn_entry = target->value.data.x_ptr.data.fn.fn_entry;
|
||||
tld_fn->fn_entry = fn_entry;
|
||||
CallingConvention cc = fn_entry->type_entry->data.fn.fn_type_id.cc;
|
||||
switch (cc) {
|
||||
case CallingConventionUnspecified: {
|
||||
|
|
|
@ -22,6 +22,7 @@ comptime {
|
|||
_ = @import("behavior/bugs/2006.zig");
|
||||
_ = @import("behavior/bugs/394.zig");
|
||||
_ = @import("behavior/bugs/421.zig");
|
||||
_ = @import("behavior/bugs/529.zig");
|
||||
_ = @import("behavior/bugs/655.zig");
|
||||
_ = @import("behavior/bugs/656.zig");
|
||||
_ = @import("behavior/bugs/704.zig");
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
const A = extern struct {
|
||||
field: c_int,
|
||||
};
|
||||
|
||||
extern fn issue529(?*A) void;
|
||||
|
||||
comptime {
|
||||
_ = @import("529_other_file_2.zig");
|
||||
}
|
||||
|
||||
test "issue 529 fixed" {
|
||||
@import("529_other_file.zig").issue529(null);
|
||||
issue529(null);
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
pub const A = extern struct {
|
||||
field: c_int,
|
||||
};
|
||||
|
||||
pub extern fn issue529(?*A) void;
|
|
@ -0,0 +1,4 @@
|
|||
pub const A = extern struct {
|
||||
field: c_int,
|
||||
};
|
||||
export fn issue529(a: ?*A) void {}
|
Loading…
Reference in New Issue