-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[stdlib] Correctly import C Int types on Windows x64 #14575
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
How important is 32-bit Windows development nowadays? How much better does the interface become if we abandon 32-bit and import |
I can't speak to the importance of 32-bit Windows development, but I can say that importing as Int64 doesn't add any friction in my experience porting a large mixed Swift/C/C++ project to 64-bit Windows. Most of the Windows APIs still deal in 32-bit arguments and return values (e.g. On the other hand, importing as |
Yeah, I think I'd come down on the long-long-as-Int64 side, since everyone else does that. It stinks about |
lib/IRGen/GenClangType.cpp
Outdated
// add mappings to C for Int and UInt. | ||
if (IGM.Triple.isOSWindows() && IGM.Triple.isArch64Bit()) { | ||
cacheStdlibType("UInt", clang::BuiltinType::ULongLong); | ||
cacheStdlibType("Int", clang::BuiltinType::LongLong); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[u]intptr_t
might be a better choice here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't find a definition for pointer types in Clang's BuiltinTypes.def
. Where would that be defined, or is there a different way we could achieve that mapping? Void
is defined if that's equivalent, but in that case I think LongLong
is clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can get Clang's choice for (u)intptr_t from clang::ASTContext::get(U)IntPtrType. There'll be a builtin type under that.
@compnerd, opinions? |
I think that 32-bit windows is still quite important. There are still a plethora of packages which are still 32-bit. I think that using |
@compnerd What specifically are your concerns? I’ve encountered no issues with it in my (>20k LOC) Swift codebase on Windows - I actually picked these issues up where a few DWORD return values from Windows APIs were getting imported as UInts and had garbage data. |
Oh, this will work fine for Windows itself, I just don't like the idea of differences across the targets. We have the ability to get this right unlike C/C++, so we should take advantage of that. I think that generalizing your change to all targets is what I would aim for. Quoting the Swift Language Reference:
It seems like the mapping being recommended here is the most portable approach, which I think we should aim to generalize it to all targets. |
What you’re specifically proposing is that I don’t have strong feelings on that, but my instinct would be that you’d just be introducing another type that differs between systems: rather than Rather, I think a better solution is just to be explicit (where possible) in the C code: use Passing an |
I could see how consistency across 64-bit platforms is more useful than consistency across 32-bit and 64-bit versions of the same OS (which is the property we'd maintain with the current version of this patch), but in practice it's way too late to change this on Apple platforms, and it's convenient that all the Apple platforms—a mix of 32-bit and 64-bit environments—use the same Swift type for I think "CLong is Int on LP64 platforms and Int32 on LLP64 platforms" is a reasonable rule, especially with size_t and intptr_t already being understood specially by the compiler everywhere. (Let's hope we don't have any ILP64 platforms to support any time soon.) |
Okay, if its not possible to get the consistency across all the targets, then lets stick with the behavior that we have on Windows. I do think that the |
@swift-ci please test |
Build failed |
Not having In short, is it more important that Swift code from other platforms works on Windows 32-bit without modification, or that Swift code works without modification between 32- and 64-bit Windows? |
Build failed |
TBH, I don't have enough of a gut feeling on which would be better here. I think that tabling that for now is the best approach. Lets get Windows x86_64 working, and then when restoring the Windows x86 build, we could easily see how painful that would be. |
I'm inclined to say |
The 'wait and see' approach sits comfortably with me. If it ends up being an issue on 32-bit Windows then it'll only be a three-line change to have 32-bit get the same behaviour as Win64, and I don't think source compatibility is going to be a concern on Windows for quite some time yet. |
Sounds like we have quorum. Could you squash the two commits, since they aren't standalone I believe and I think we should get this in then. |
c11d852
to
457ac78
Compare
Commits squashed. No changes since the tests passed but feel free to test again if you'd like. |
Still need to at least smoke test to be allowed to merge, so @swift-ci Please smoke test |
@swift-ci please smoke test macOS platform |
64-bit Windows is an LLP64 architecture; unlike on other 64-bit platforms,
long
is a 32-bit type. This means we don't have a one-to-one mapping betweenCInt
/Int32
,CLong
/Int
,CLongLong
/Int64
like we do on other platforms.Instead, import
long
asInt32
andlong long
asInt64
. An alternative would be to importlong long
asInt
; however, that would mean that code would require changes in many cases between 32-bit and 64-bit Windows.Since there's no direct mapping from a C type to
Int
, manually create mappings back fromInt
tolong long
.Do the same for unsigned data types.