Add is_dll_import to @extern, to support __declspec(dllimport) with the MSVC ABI#21758
Add is_dll_import to @extern, to support __declspec(dllimport) with the MSVC ABI#21758andrewrk merged 4 commits intoziglang:masterfrom
is_dll_import to @extern, to support __declspec(dllimport) with the MSVC ABI#21758Conversation
…t in a comptime scope. Add a note about thread local / dll import being the cause.
It wouldn't make sense to have passe `.export` here, and that was in fact a compile error - so simply make this a bool instead.
37afc74 to
4817655
Compare
- tests/standalone/extern wasn't running its test step - add compile error tests for thread local / dll import @extern in a comptime scope
4817655 to
7edd69d
Compare
|
Good work, I was going to press merge but then I saw this question:
what does this have to do with optionals? seems to have to only do with comptime? |
|
What I meant there is that I expected to able to apply this diff and have this test pass: --- a/test/cases/compile_errors/builtin_extern_in_comptime_scope.zig
+++ b/test/cases/compile_errors/builtin_extern_in_comptime_scope.zig
@@ -1,5 +1,7 @@
const foo_tl = @extern(*i32, .{ .name = "foo", .is_thread_local = true });
+const opt_tl = @extern(?*i32, .{ .name = "foo", .is_thread_local = true });
const foo_dll = @extern(*i32, .{ .name = "foo", .is_dll_import = true });
+const opt_dll = @extern(?*i32, .{ .name = "foo", .is_dll_import = true });
pub export fn entry() void {
_ = foo_tl;
}
@@ -13,6 +15,12 @@ pub export fn entry2() void {
// :1:16: error: unable to resolve comptime value
// :1:16: note: global variable initializer must be comptime-known
// :1:16: note: thread local and dll imported variables have runtime-known addresses
+// :2:16: error: unable to resolve comptime value
+// :2:16: note: global variable initializer must be comptime-known
+// :2:16: note: thread local and dll imported variables have runtime-known addresses
// :3:17: error: unable to resolve comptime value
// :3:17: note: global variable initializer must be comptime-known
// :3:17: note: thread local and dll imported variables have runtime-known addresses
+// :4:17: error: unable to resolve comptime value
+// :4:17: note: global variable initializer must be comptime-known
+// :4:17: note: thread local and dll imported variables have runtime-known addressesBut in reality there are no compile errors for the I'm happy to leave that enhancement to a future PR though - assuming my assumption about those being compile errors is correct. |
|
I agree with you, that test should pass. However I see no need for it to block this nice patch. Thanks! |
Closes #15903
Closes #21749
This change adds
is_dll_import: boolto the options to@extern. This has the effect of setting the LLVM DLL Storage Class of the global todllimport, which then generates the correct code to load from such a symbol at runtime - by prepending__imp_to the symbol name and loading from that symbol instead.This is necessary for the
msvcABI, as the "auto imports" features that make this work on-gnuare MinGW specific and don't exist there (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fauto-import).As part of this change I also added an error note that explains why you can't place an
@externthat uses eitheris_thread_localoris_dll_importin a comptime scope (because the address is runtime-known). To do this I added a new optional field toNeededComptimeReasonwhich does seem a bit heavy-handed since it's only used in this one place - I can easily change this to build one single, longerneeded_comptime_reasonif that is preferred.Other changes:
tests/standalone/externwasn't actually running the test step, that is fixed nowA question for reviewers about existing behaviour:
No compile errors are currently emitted when using optional pointers in
@externin comptime scopes - as an example:This doesn't result in a compile error, but a linker error instead, because a
@main.foo_opt_dataglobal is generated that is initialized from a non-existent symbol@foo_opt_data, this can't be available at comptime because the value is only known at runtime.I tried to determine the cause for this, and I thought it was
isPtrRuntimeValuenot unwrapping the optional properly when getting the backing nav, but it seems to handle that inip.getBackinNav. I'm happy to fix this as part of this pr and add a compile error test case for this tobuiltin_extern_in_comptime_scope, if someone can point me in the right direction.