From 56dfb08727dc9a33142050c09865f1ddf29652af Mon Sep 17 00:00:00 2001 From: Hugh Bellamy Date: Mon, 28 Nov 2016 17:07:27 +0000 Subject: [PATCH 1/2] Port swift/basic to Windows --- include/swift/Basic/EncodedSequence.h | 11 ++- include/swift/Basic/ImmutablePointerSet.h | 2 +- include/swift/Basic/type_traits.h | 6 +- lib/Basic/SourceLoc.cpp | 2 +- lib/Basic/UUID.cpp | 81 ++++++++++++++++++++--- lib/Basic/Version.cpp | 9 ++- 6 files changed, 96 insertions(+), 15 deletions(-) diff --git a/include/swift/Basic/EncodedSequence.h b/include/swift/Basic/EncodedSequence.h index fb4695547370b..9d26a902e8dae 100644 --- a/include/swift/Basic/EncodedSequence.h +++ b/include/swift/Basic/EncodedSequence.h @@ -337,11 +337,20 @@ class EncodedSequence : public EncodedSequenceBase { /// see the documentation there for information about how to use this /// data structure. template class Map { + // Hack: MSVC isn't able to resolve the InlineKeyCapacity part of the + // template of PrefixMap, so we have to split it up and pass it manually. +#if defined(_MSC_VER) + static const size_t Size = (sizeof(void*) - 1) / sizeof(Chunk); + static const size_t ActualSize = max(Size, 1); + + using MapBase = PrefixMap; +#else using MapBase = PrefixMap; +#endif MapBase TheMap; public: - using SequenceIterator = EncodedSequence::iterator; + using SequenceIterator = typename EncodedSequence::iterator; using KeyType = typename MapBase::KeyType; using Handle = typename MapBase::Handle; diff --git a/include/swift/Basic/ImmutablePointerSet.h b/include/swift/Basic/ImmutablePointerSet.h index 77d5855859edb..636f4cab1e480 100644 --- a/include/swift/Basic/ImmutablePointerSet.h +++ b/include/swift/Basic/ImmutablePointerSet.h @@ -112,7 +112,7 @@ template class ImmutablePointerSet : public llvm::FoldingSetNode { return *LowerBound == Ptr; } - using iterator = typename decltype(Data)::iterator; + using iterator = typename ArrayRef::iterator; iterator begin() const { return Data.begin(); } iterator end() const { return Data.end(); } diff --git a/include/swift/Basic/type_traits.h b/include/swift/Basic/type_traits.h index cc4dfbfb2d797..455e86432b129 100644 --- a/include/swift/Basic/type_traits.h +++ b/include/swift/Basic/type_traits.h @@ -29,7 +29,7 @@ namespace swift { /// is not intended to be specialized. template struct IsTriviallyCopyable { -#if _LIBCPP_VERSION +#if _LIBCPP_VERSION || (defined(_MSC_VER) && !defined(__clang__)) // libc++ implements it. static const bool value = std::is_trivially_copyable::value; #elif __has_feature(is_trivially_copyable) @@ -41,7 +41,7 @@ struct IsTriviallyCopyable { template struct IsTriviallyConstructible { -#if _LIBCPP_VERSION +#if _LIBCPP_VERSION || (defined(_MSC_VER) && !defined(__clang__)) // libc++ implements it. static const bool value = std::is_trivially_constructible::value; #elif __has_feature(has_trivial_constructor) @@ -53,7 +53,7 @@ struct IsTriviallyConstructible { template struct IsTriviallyDestructible { -#if _LIBCPP_VERSION +#if _LIBCPP_VERSION || (defined(_MSC_VER) && !defined(__clang__)) // libc++ implements it. static const bool value = std::is_trivially_destructible::value; #elif __has_feature(has_trivial_destructor) diff --git a/lib/Basic/SourceLoc.cpp b/lib/Basic/SourceLoc.cpp index e1b3d1a2a3d51..f7c6190b86b21 100644 --- a/lib/Basic/SourceLoc.cpp +++ b/lib/Basic/SourceLoc.cpp @@ -24,7 +24,7 @@ void SourceManager::verifyAllBuffers() const { }; // FIXME: This depends on the buffer IDs chosen by llvm::SourceMgr. - __attribute__((used)) static char arbitraryTotal = 0; + LLVM_ATTRIBUTE_USED static char arbitraryTotal = 0; for (unsigned i = 1, e = LLVMSourceMgr.getNumBuffers(); i <= e; ++i) { auto *buffer = LLVMSourceMgr.getMemoryBuffer(i); if (buffer->getBufferSize() == 0) diff --git a/lib/Basic/UUID.cpp b/lib/Basic/UUID.cpp index b107b34ae401f..ebf024c6b8c3f 100644 --- a/lib/Basic/UUID.cpp +++ b/lib/Basic/UUID.cpp @@ -15,40 +15,105 @@ // //===----------------------------------------------------------------------===// -#include #include "swift/Basic/UUID.h" +// WIN32 doesn't natively support . Instead, we use Win32 APIs. +#if defined(_WIN32) +#define WIN32_LEAN_AND_MEAN +#include +#include +#else +#include +#endif + using namespace swift; -UUID::UUID(FromRandom_t) { +swift::UUID::UUID(FromRandom_t) { +#if defined(_WIN32) + ::UUID uuid; + UuidCreate(&uuid); + + memcpy(Value, &uuid, Size); +#else uuid_generate_random(Value); +#endif } -UUID::UUID(FromTime_t) { +swift::UUID::UUID(FromTime_t) { +#if defined(_WIN32) + ::UUID uuid; + UuidCreate(&uuid); + + memcpy(Value, &uuid, Size); +#else uuid_generate_time(Value); +#endif } -UUID::UUID() { +swift::UUID::UUID() { +#if defined(_WIN32) + ::UUID uuid = *((::UUID *)&Value); + UuidCreateNil(&uuid); + + memcpy(Value, &uuid, Size); +#else uuid_clear(Value); +#endif } -Optional UUID::fromString(const char *s) { - UUID result; +Optional swift::UUID::fromString(const char *s) { +#if defined(_WIN32) + RPC_CSTR t = const_cast(reinterpret_cast(s)); + + ::UUID uuid; + RPC_STATUS status = UuidFromStringA(t, &uuid); + if (status == RPC_S_INVALID_STRING_UUID) { + return None; + } + + swift::UUID result = UUID(); + memcpy(result.Value, &uuid, Size); + return result; +#else + swift::UUID result; if (uuid_parse(s, result.Value)) return None; return result; +#endif } -void UUID::toString(llvm::SmallVectorImpl &out) const { +void swift::UUID::toString(llvm::SmallVectorImpl &out) const { out.resize(UUID::StringBufferSize); +#if defined(_WIN32) + ::UUID uuid; + memcpy(&uuid, Value, Size); + + RPC_CSTR str; + UuidToStringA(&uuid, &str); + + char* signedStr = reinterpret_cast(str); + memcpy(out.data(), signedStr, StringBufferSize); +#else uuid_unparse_upper(Value, out.data()); +#endif // Pop off the null terminator. assert(out.back() == '\0' && "did not null-terminate?!"); out.pop_back(); } -int UUID::compare(UUID y) const { +int swift::UUID::compare(UUID y) const { +#if defined(_WIN32) + RPC_STATUS s; + ::UUID uuid1; + memcpy(&uuid1, Value, Size); + + ::UUID uuid2; + memcpy(&uuid2, y.Value, Size); + + return UuidCompare(&uuid1, &uuid2, &s); +#else return uuid_compare(Value, y.Value); +#endif } llvm::raw_ostream &swift::operator<<(llvm::raw_ostream &os, UUID uuid) { diff --git a/lib/Basic/Version.cpp b/lib/Basic/Version.cpp index 1e859749e3e1c..1af6c6b254c62 100644 --- a/lib/Basic/Version.cpp +++ b/lib/Basic/Version.cpp @@ -43,6 +43,12 @@ SWIFT_MAKE_VERSION_STRING(SWIFT_VERSION_MAJOR, SWIFT_VERSION_MINOR) #endif +// MSVC doesn't support __has_include +#if defined(_MSC_VER) +# include "LLVMRevision.inc" +# include "ClangRevision.inc" +# include "SwiftRevision.inc" +#else #if __has_include("LLVMRevision.inc") # include "LLVMRevision.inc" #endif @@ -52,6 +58,7 @@ #if __has_include("SwiftRevision.inc") # include "SwiftRevision.inc" #endif +#endif namespace swift { namespace version { @@ -401,7 +408,7 @@ std::string getSwiftFullVersion(Version effectiveVersion) { #endif // Suppress unused function warning - (void) printFullRevisionString; + (void)&printFullRevisionString; return OS.str(); } From 50e94af377580382dcf8a43ab02fdcfb6f34a5f9 Mon Sep 17 00:00:00 2001 From: Hugh Bellamy Date: Fri, 2 Dec 2016 17:01:00 +0000 Subject: [PATCH 2/2] Generate empty *Revision.inc files during the build process --- lib/Basic/CMakeLists.txt | 21 ++++++++++++--------- lib/Basic/Version.cpp | 19 +++---------------- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/lib/Basic/CMakeLists.txt b/lib/Basic/CMakeLists.txt index 47779cd69cb1a..2c4f1079ecba6 100644 --- a/lib/Basic/CMakeLists.txt +++ b/lib/Basic/CMakeLists.txt @@ -31,10 +31,10 @@ set(get_svn_script "${LLVM_MAIN_SRC_DIR}/cmake/modules/GetSVN.cmake") function(generate_revision_inc revision_inc_var name dir) find_first_existing_vc_file(dep_file "${dir}") + # Create custom target to generate the VC revision include. + set(revision_inc "${CMAKE_CURRENT_BINARY_DIR}/${name}Revision.inc") + string(TOUPPER ${name} upper_name) if(DEFINED dep_file) - # Create custom target to generate the VC revision include. - set(revision_inc "${CMAKE_CURRENT_BINARY_DIR}/${name}Revision.inc") - string(TOUPPER ${name} upper_name) add_custom_command(OUTPUT "${revision_inc}" DEPENDS "${dep_file}" "${get_svn_script}" COMMAND @@ -42,13 +42,16 @@ function(generate_revision_inc revision_inc_var name dir) "-DFIRST_NAME=${upper_name}" "-DHEADER_FILE=${revision_inc}" -P "${get_svn_script}") - - # Mark the generated header as being generated. - set_source_files_properties("${revision_inc}" - PROPERTIES GENERATED TRUE - HEADER_FILE_ONLY TRUE) - set(${revision_inc_var} ${revision_inc} PARENT_SCOPE) + else() + # Generate an empty Revision.inc file if we are not using git or SVN. + file(WRITE "${revision_inc}" "") endif() + + # Mark the generated header as being generated. + set_source_files_properties("${revision_inc}" + PROPERTIES GENERATED TRUE + HEADER_FILE_ONLY TRUE) + set(${revision_inc_var} ${revision_inc} PARENT_SCOPE) endfunction() generate_revision_inc(llvm_revision_inc LLVM "${LLVM_MAIN_SRC_DIR}") diff --git a/lib/Basic/Version.cpp b/lib/Basic/Version.cpp index 1af6c6b254c62..73634d94962d8 100644 --- a/lib/Basic/Version.cpp +++ b/lib/Basic/Version.cpp @@ -43,22 +43,9 @@ SWIFT_MAKE_VERSION_STRING(SWIFT_VERSION_MAJOR, SWIFT_VERSION_MINOR) #endif -// MSVC doesn't support __has_include -#if defined(_MSC_VER) -# include "LLVMRevision.inc" -# include "ClangRevision.inc" -# include "SwiftRevision.inc" -#else -#if __has_include("LLVMRevision.inc") -# include "LLVMRevision.inc" -#endif -#if __has_include("ClangRevision.inc") -# include "ClangRevision.inc" -#endif -#if __has_include("SwiftRevision.inc") -# include "SwiftRevision.inc" -#endif -#endif +#include "LLVMRevision.inc" +#include "ClangRevision.inc" +#include "SwiftRevision.inc" namespace swift { namespace version {