Skip to content

Port swift/basic to Windows using MSVC #5949

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

Merged
merged 2 commits into from
Dec 2, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion include/swift/Basic/EncodedSequence.h
Original file line number Diff line number Diff line change
Expand Up @@ -337,11 +337,20 @@ class EncodedSequence : public EncodedSequenceBase {
/// see the documentation there for information about how to use this
/// data structure.
template <class ValueType> 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_t>(Size, 1);

using MapBase = PrefixMap<Chunk, ValueType, ActualSize>;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#else
using MapBase = PrefixMap<Chunk, ValueType>;
#endif
MapBase TheMap;

public:
using SequenceIterator = EncodedSequence::iterator;
using SequenceIterator = typename EncodedSequence::iterator;
Copy link
Contributor Author

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 Clang deficiency rather than an MSVC deficiency

Copy link
Contributor

@jckarter jckarter Dec 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, typename ought to be required by the standard. (Assuming EncodedSequence is dependent, of course.)

using KeyType = typename MapBase::KeyType;
using Handle = typename MapBase::Handle;

Expand Down
2 changes: 1 addition & 1 deletion include/swift/Basic/ImmutablePointerSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ template <typename T> class ImmutablePointerSet : public llvm::FoldingSetNode {
return *LowerBound == Ptr;
}

using iterator = typename decltype(Data)::iterator;
using iterator = typename ArrayRef<PtrTy>::iterator;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iterator begin() const { return Data.begin(); }
iterator end() const { return Data.end(); }

Expand Down
6 changes: 3 additions & 3 deletions include/swift/Basic/type_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ namespace swift {
/// is not intended to be specialized.
template<typename T>
struct IsTriviallyCopyable {
#if _LIBCPP_VERSION
#if _LIBCPP_VERSION || (defined(_MSC_VER) && !defined(__clang__))
// libc++ implements it.
static const bool value = std::is_trivially_copyable<T>::value;
#elif __has_feature(is_trivially_copyable)
Expand All @@ -41,7 +41,7 @@ struct IsTriviallyCopyable {

template<typename T>
struct IsTriviallyConstructible {
#if _LIBCPP_VERSION
#if _LIBCPP_VERSION || (defined(_MSC_VER) && !defined(__clang__))
// libc++ implements it.
static const bool value = std::is_trivially_constructible<T>::value;
#elif __has_feature(has_trivial_constructor)
Expand All @@ -53,7 +53,7 @@ struct IsTriviallyConstructible {

template<typename T>
struct IsTriviallyDestructible {
#if _LIBCPP_VERSION
#if _LIBCPP_VERSION || (defined(_MSC_VER) && !defined(__clang__))
// libc++ implements it.
static const bool value = std::is_trivially_destructible<T>::value;
#elif __has_feature(has_trivial_destructor)
Expand Down
21 changes: 12 additions & 9 deletions lib/Basic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,27 @@ 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
${CMAKE_COMMAND} "-DFIRST_SOURCE_DIR=${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}")
Expand Down
2 changes: 1 addition & 1 deletion lib/Basic/SourceLoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
81 changes: 73 additions & 8 deletions lib/Basic/UUID.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,40 +15,105 @@
//
//===----------------------------------------------------------------------===//

#include <uuid/uuid.h>
#include "swift/Basic/UUID.h"

// WIN32 doesn't natively support <uuid/uuid.h>. Instead, we use Win32 APIs.
#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
#include <rpc.h>
#include <string>
#else
#include <uuid/uuid.h>
#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> UUID::fromString(const char *s) {
UUID result;
Optional<swift::UUID> swift::UUID::fromString(const char *s) {
#if defined(_WIN32)
RPC_CSTR t = const_cast<RPC_CSTR>(reinterpret_cast<const unsigned char*>(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<char> &out) const {
void swift::UUID::toString(llvm::SmallVectorImpl<char> &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<char*>(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) {
Expand Down
14 changes: 4 additions & 10 deletions lib/Basic/Version.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,9 @@
SWIFT_MAKE_VERSION_STRING(SWIFT_VERSION_MAJOR, SWIFT_VERSION_MINOR)
#endif

#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
#include "LLVMRevision.inc"
#include "ClangRevision.inc"
#include "SwiftRevision.inc"

namespace swift {
namespace version {
Expand Down Expand Up @@ -401,7 +395,7 @@ std::string getSwiftFullVersion(Version effectiveVersion) {
#endif

// Suppress unused function warning
(void) printFullRevisionString;
(void)&printFullRevisionString;

return OS.str();
}
Expand Down