diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-03-02 14:51:29 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-03-02 14:51:29 -0500 |
| commit | 446324a1d82514157f5a11a6ca775711bc48c419 (patch) | |
| tree | 3a6c1fb0fe76ff999cc89a03aa7f09fdc8cf5c5b /src/codegen | |
| parent | 7fc8dd66427dd0abed5ca9195e6afdbb687bd5f5 (diff) | |
| parent | 403a1fe5d767e801b58fc706eaa54f1171ae27de (diff) | |
| download | zig-446324a1d82514157f5a11a6ca775711bc48c419.tar.gz zig-446324a1d82514157f5a11a6ca775711bc48c419.zip | |
Merge pull request #11025 from Vexu/stage2
stage2: implement `@extern`
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/llvm.zig | 18 | ||||
| -rw-r--r-- | src/codegen/llvm/bindings.zig | 11 |
2 files changed, 27 insertions, 2 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index fa29a1aae3..5ef62aadcb 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -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); } diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig index c505a7d045..a3f7ff9561 100644 --- a/src/codegen/llvm/bindings.zig +++ b/src/codegen/llvm/bindings.zig @@ -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, |
