-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Support building swift/AST with MSVC on Windows #5948
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
lib/AST/ASTMangler.cpp
Outdated
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.
@eeckstein PTAL, this changes your recently committed code - I think this was a case of Clang allowing something that perhaps isn't spec-ed C++?
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.
Yeah, this just looks like a mistake.
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.
yes, it was
include/swift/AST/Module.h
Outdated
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.
This fixes an MSVC error: cannot instantiate abstract class FileUnit. I'm not sure how correct this is (@jrose-apple you seem to know a lot of these sorts of things)
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.
Definitely not correct, except coincidentally. Also confused; this operator occurs within the definition of FileUnit, so I would expect it to be able to calculate the alignment.
…well, okay, maybe not, that might require two passes. *goes to check C++ standard*
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.
Okay, this actually does look correct—"When alignof is applied to a reference type, the result shall be the alignment of the referenced type." (C++11 [expr.alignof]p3)—but if MSVC is accepting one and not the other I'm a little concerned that it's doing the wrong thing. Can you test that it accepts this code?
struct Foo {
bool b;
static_assert(alignof(Foo&) == alignof(bool), "aligning reference rather than Foo");
};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.
Specific citation allowing this (which says nothing to whether MSVC implements it): "Within the class member-specification, the class is regarded as complete within function bodies, default arguments, and brace-or-equal-initializers for non-static data members (including such things in nested classes)." (C++11 [class.mem]p2)
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.
The following modification of your example works:
struct Foo {
bool b;
};
static_assert(alignof(Foo&) == alignof(bool), "aligning reference rather than Foo");
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.
Hmm, something like this:
class FileUnit {
public:
// Only allow allocation of FileUnits using the allocator in ASTContext
// or by doing a placement new.
void *operator new(size_t Bytes, ASTContext &C,
unsigned Alignment = alignOfFileUnit());
};
static inline unsigned alignOfFileUnit() {
return alignof(FileUnit);
}
doesn't work due to same error:
1>C:\Users\Lukey\Documents\GitHub\my-swift\swift\include\swift/AST/Module.h(757): error C2259: 'swift::FileUnit': cannot instantiate abstract class (compiling source file C:\Users\Lukey\Documents\GitHub\my-swift\swift\lib\AST\ASTPrinter.cpp)
1> C:\Users\Lukey\Documents\GitHub\my-swift\swift\include\swift/AST/Module.h(757): note: due to following members: (compiling source file C:\Users\Lukey\Documents\GitHub\my-swift\swift\lib\AST\ASTPrinter.cpp)
1> C:\Users\Lukey\Documents\GitHub\my-swift\swift\include\swift/AST/Module.h(757): note: 'void swift::FileUnit::lookupValue(swift::ModuleDecl::AccessPathTy,swift::DeclName,swift::NLKind,llvm::SmallVectorImpl<swift::ValueDecl *> &) const': is abstract (compiling source file C:\Users\Lukey\Documents\GitHub\my-swift\swift\lib\AST\ASTPrinter.cpp)
1> C:\Users\Lukey\Documents\GitHub\my-swift\swift\include\swift/AST/Module.h(556): note: see declaration of 'swift::FileUnit::lookupValue' (compiling source file C:\Users\Lukey\Documents\GitHub\my-swift\swift\lib\AST\ASTPrinter.cpp)
1> C:\Users\Lukey\Documents\GitHub\my-swift\swift\include\swift/AST/Module.h(757): note: 'void swift::FileUnit::lookupObjCMethods(swift::ObjCSelector,llvm::SmallVectorImpl<swift::AbstractFunctionDecl *> &) const': is abstract (compiling source file C:\Users\Lukey\Documents\GitHub\my-swift\swift\lib\AST\ASTPrinter.cpp)
1> C:\Users\Lukey\Documents\GitHub\my-swift\swift\include\swift/AST/Module.h(588): note: see declaration of 'swift::FileUnit::lookupObjCMethods' (compiling source file C:\Users\Lukey\Documents\GitHub\my-swift\swift\lib\AST\ASTPrinter.cpp)
1> C:\Users\Lukey\Documents\GitHub\my-swift\swift\include\swift/AST/Module.h(757): note: 'swift::Identifier swift::FileUnit::getDiscriminatorForPrivateValue(const swift::ValueDecl *) const': is abstract (compiling source file C:\Users\Lukey\Documents\GitHub\my-swift\swift\lib\AST\ASTPrinter.cpp)
1> C:\Users\Lukey\Documents\GitHub\my-swift\swift\include\swift/AST/Module.h(631): note: see declaration of 'swift::FileUnit::getDiscriminatorForPrivateValue' (compiling source file C:\Users\Lukey\Documents\GitHub\my-swift\swift\lib\AST\ASTPrinter.cpp)
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.
Ah, that's a much more enlightening error. I forgot about the virtual function.
Does the reference do the right thing now?
class Test {
alignas(16) double x;
public:
virtual void foo() = 0;
};
static_assert(alignof(Test&) == 16, "");(Of course, maybe MSVC doesn't support overalignment, in which case the test won't work again.)
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.
This console application compiles and runs just fine
// ConsoleApplication2.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <string>
#include <io.h>
class Test {
alignas(16) double x;
public:
virtual void foo() = 0;
};
static_assert(alignof(Test&) == 16, "");
int main()
{
}
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.
Okay, then in that case we can use alignof(FileUnit&) in alignOfFileUnit and we should get the correct answer.
(I think this is actually important because DeclContexts are deliberately overaligned, and we rely on that to cram things in the low bits.)
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.
include/swift/AST/AnyFunctionRef.h
Outdated
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.
Clang still has unknown pragma warnings on, so this should be guarded by a check for MSVC.
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.
ah I assumed if this worked with clang-cl it would work with Clang, but I was wrong - fixed
include/swift/AST/Decl.h
Outdated
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.
What does MSVC consider a reference that Clang doesn't?
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 get the following error
error C2280: 'void *swift::AST::ModuleDecl::__delDtor(unsigned int)': attempting to reference a deleted function
The problem seems to be that MSVC generates this __delDtor intrinsic that I don't seem to have control over.
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.
Take a look at this link: https://msdn.microsoft.com/en-us/library/mt723604.aspx
There seems to be some mention of this error, but I'm not sure how applicable this is, so I'd appreciate your expertise
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.
Ah, maybe you would then have to delete operator delete in all the subclasses too.
It's possible marking it virtual would work?
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.
Ah, maybe you would then have to delete operator delete in all the subclasses too.
This doesn't work - it just changes the error message from
void swift::Decl::operator delete(void *)': attempting to reference a deleted function
to
void swift::ModuleDecl::operator delete(void *)': attempting to reference a deleted function
Making it virtual causes the error
'delete' cannot be a virtual function
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.
All right, oh well. We can do the workaround.
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.
This looks like an MSVC bug. I presume the deleting destructor is part of its ABI, but that entry point seems like it ought to be transitively delete-d if operator delete is deleted.
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 believe it's an MSVC bug, but I don't mind us working around it for now.
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've submitted a connect bug for this, at https://connect.microsoft.com/VisualStudio/feedback/details/3116505
include/swift/AST/Expr.h
Outdated
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.
This seems really brittle. I still don't like it, but I don't have an alternative to play with right now.
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 hate this too, but seems to be the best I can figure out
include/swift/AST/LookupKinds.h
Outdated
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.
If you're going to do this, just write the constant unconditionally, and static_assert that it has the correct value.
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 seem to reproduce this - I think it is a Visual Studio bug. I've removed the workaround
lib/AST/ASTMangler.cpp
Outdated
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.
Yeah, this just looks like a mistake.
lib/AST/NameLookup.cpp
Outdated
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.
We can just include <cassert> unconditionally. What's intrin.h for?
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.
Oh, I see, it's the popcnt check below. I think it's fine to leave that out, since the static_assert will be checked in Clang anyway.
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.
Sorry - I'm a tad confused. Do you suggest not changing this file, or simply to move <cassert> out of the if
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.
Ah, both. :-) Please move <cassert> out of the #if, but don't bother asserting the popcount under MSVC (just #if it out).
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.
fixed, thanks
|
I've rebased and addressed your comments about the alignment issues |
jrose-apple
left a comment
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.
Just a few last comments.
lib/AST/ASTContext.cpp
Outdated
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.
More unguarded pragmas. Also, I find it hard to believe that we'd get a warning on this code and not the previous line, so maybe this is no longer necessary?
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.
We do get the following warning:
C:\Users\Lukey\Documents\GitHub\my-swift\swift\lib\AST\ASTContext.cpp(282): warning C4189: 'conformance': local variable is initialized but not referenced
very weird...
lib/AST/ASTDumper.cpp
Outdated
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.
:-(
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.
(To be clear, no action requested. This just seems like a horrible oversight on MSVC's part.)
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.
Okay, I have a much better fix that suddenly came to me when you commented. Basically, the problem was that the code referring to this << operator is in an anonymous namespace. Moving << into that anonymous namespace fixes this. Unfortunately, MSVC wasn't very helpful as it reported the error as an ambiguous overload error for unsigned char
lib/AST/ASTMangler.cpp
Outdated
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.
Why the change here? These do different things. cc @eeckstein
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.
whoops - merge conflict
lib/AST/ASTDumper.cpp
Outdated
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.
Tabs snuck in 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.
Thanks - this should be fixed now
|
I've made a connect bug for the numTrailingObjects problem: https://connect.microsoft.com/VisualStudio/feedback/details/3116517 If anyone's curious, they can try coming up with a better workaround by compiling MSVC code online here: http://rextester.com/XIJ43194 |
include/swift/AST/AnyFunctionRef.h
Outdated
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.
include/swift/AST/Types.h
Outdated
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.
lib/AST/ASTContext.cpp
Outdated
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.
This seems to be a bug in MSVC: I've been trying hard to reproduce this came, but can't.
lib/AST/ASTDumper.cpp
Outdated
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.
Again, this looks to be an MSVC bug, but I can't reproduce it :(
|
@slavapestov PTAL. I think the only thing holding back this one getting merged is the gross hack for https://connect.microsoft.com/VisualStudio/feedback/details/3116517. I'd like to figure out a work around that doesn't make us diverge from upstream LLVM. If anyone has some spare time, check out a simple reproduction here and help me find a nicer fix for MSVC's bug: http://rextester.com/XIJ43194. This one also lets you compile C++ online if you don't have a Windows PC |
|
@swift-ci Please smoke test |
Relies on apple/swift-llvm#33 but can be merged before