stage2: implement @extern

This commit is contained in:
Veikka Tuominen
2022-02-28 16:12:01 +02:00
parent 7cfc3f0cfa
commit ef4aca2dc4
4 changed files with 124 additions and 6 deletions

View File

@@ -548,6 +548,10 @@ pub const Object = struct {
llvm_global.setValueName(decl.name);
llvm_global.setUnnamedAddr(.False);
llvm_global.setLinkage(.External);
if (decl.val.castTag(.variable)) |variable| {
if (variable.data.is_threadlocal) llvm_global.setThreadLocalMode(.GeneralDynamicTLSModel);
if (variable.data.is_weak_linkage) llvm_global.setLinkage(.ExternalWeak);
}
} else if (exports.len != 0) {
const exp_name = exports[0].options.name;
llvm_global.setValueName2(exp_name.ptr, exp_name.len);
@@ -558,6 +562,9 @@ pub const Object = struct {
.Weak => llvm_global.setLinkage(.WeakODR),
.LinkOnce => llvm_global.setLinkage(.LinkOnceODR),
}
if (decl.val.castTag(.variable)) |variable| {
if (variable.data.is_threadlocal) llvm_global.setThreadLocalMode(.GeneralDynamicTLSModel);
}
// If a Decl is exported more than one time (which is rare),
// we add aliases for all but the first export.
// TODO LLVM C API does not support deleting aliases. We need to
@@ -788,8 +795,15 @@ pub const DeclGen = struct {
const llvm_global = dg.object.llvm_module.addGlobalInAddressSpace(llvm_type, fqn, llvm_addrspace);
gop.value_ptr.* = llvm_global;
const is_extern = decl.val.tag() == .unreachable_value;
if (!is_extern) {
if (decl.isExtern()) {
llvm_global.setValueName(decl.name);
llvm_global.setUnnamedAddr(.False);
llvm_global.setLinkage(.External);
if (decl.val.castTag(.variable)) |variable| {
if (variable.data.is_threadlocal) llvm_global.setThreadLocalMode(.GeneralDynamicTLSModel);
if (variable.data.is_weak_linkage) llvm_global.setLinkage(.ExternalWeak);
}
} else {
llvm_global.setLinkage(.Internal);
llvm_global.setUnnamedAddr(.True);
}

View File

@@ -120,6 +120,9 @@ pub const Value = opaque {
pub const setUnnamedAddr = LLVMSetUnnamedAddr;
extern fn LLVMSetUnnamedAddr(Global: *const Value, HasUnnamedAddr: Bool) void;
pub const setThreadLocalMode = LLVMSetThreadLocalMode;
extern fn LLVMSetThreadLocalMode(Global: *const Value, Mode: ThreadLocalMode) void;
pub const deleteGlobal = LLVMDeleteGlobal;
extern fn LLVMDeleteGlobal(GlobalVar: *const Value) void;
@@ -1230,6 +1233,14 @@ pub const Linkage = enum(c_uint) {
LinkerPrivateWeak,
};
pub const ThreadLocalMode = enum(c_uint) {
NotThreadLocal,
GeneralDynamicTLSModel,
LocalDynamicTLSModel,
InitialExecTLSModel,
LocalExecTLSModel,
};
pub const AtomicOrdering = enum(c_uint) {
NotAtomic = 0,
Unordered = 1,