diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b1b6df8fcfa4..a98c7438670d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -455,6 +455,19 @@ elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD") set(SWIFT_PRIMARY_VARIANT_SDK_default "FREEBSD") set(SWIFT_PRIMARY_VARIANT_ARCH_default "x86_64") +elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN") + configure_sdk_unix(CYGWIN "Cygwin" "windows" "cygwin" "x86_64" "x86_64-unknown-windows-cygnus") + +# set(CMAKE_EXECUTABLE_FORMAT "ELF") + + set(SWIFT_HOST_VARIANT "windows" CACHE STRING + "Deployment OS for Swift host tools (the compiler) [windows].") + + set(SWIFT_HOST_VARIANT_SDK "CYGWIN") + set(SWIFT_HOST_VARIANT_ARCH "x86_64") + + set(SWIFT_PRIMARY_VARIANT_SDK_default "CYGWIN") + set(SWIFT_PRIMARY_VARIANT_ARCH_default "x86_64") elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") # Set defaults. diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake index 2e9479c8359a1..a34fea6183c3e 100644 --- a/cmake/modules/AddSwift.cmake +++ b/cmake/modules/AddSwift.cmake @@ -182,6 +182,8 @@ function(_add_variant_link_flags list(APPEND result "-lpthread" "-ldl") elseif("${sdk}" STREQUAL "FREEBSD") list(APPEND result "-lpthread") + elseif("${sdk}" STREQUAL "CYGWIN") + # No extra libraries required. else() list(APPEND result "-lobjc") endif() @@ -967,6 +969,10 @@ function(_add_swift_library_single target name) set_target_properties("${target}" PROPERTIES INSTALL_RPATH "$ORIGIN:/usr/lib/swift/linux") + elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Cygwin") + set_target_properties("${target}" + PROPERTIES + INSTALL_RPATH "$ORIGIN:/usr/lib/swift/windows") endif() set_target_properties("${target}" PROPERTIES BUILD_WITH_INSTALL_RPATH YES) diff --git a/include/swift/AST/IRGenOptions.h b/include/swift/AST/IRGenOptions.h index 414ab7e2db248..35d9e2f7ee123 100644 --- a/include/swift/AST/IRGenOptions.h +++ b/include/swift/AST/IRGenOptions.h @@ -64,6 +64,9 @@ class IRGenOptions { /// The compilation directory for the debug info. std::string DebugCompilationDir; + /// The DWARF version of debug info. + unsigned DWARFVersion; + /// The command line string that is to be stored in the DWARF debug info. std::string DWARFDebugFlags; diff --git a/include/swift/Basic/Dwarf.h b/include/swift/Basic/Dwarf.h index c568990d3e8a0..34524d28e9af7 100644 --- a/include/swift/Basic/Dwarf.h +++ b/include/swift/Basic/Dwarf.h @@ -21,7 +21,9 @@ namespace swift { /// The DWARF version emitted by the Swift compiler. - const unsigned DWARFVersion = 3; + const unsigned GenericDWARFVersion = 3; + const unsigned CygwinDWARFVersion = 4; + static const char MachOASTSegmentName[] = "__SWIFT"; static const char MachOASTSectionName[] = "__ast"; static const char ELFASTSectionName[] = ".swift_ast"; diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index ec9c7654be43e..389d827a80ff3 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -181,6 +181,7 @@ namespace swift { } else if (Target.isWatchOS()) { Target.getOSVersion(major, minor, revision); } else if (Target.isOSLinux() || Target.isOSFreeBSD() || + Target.isOSWindows() || Target.getTriple().empty()) { major = minor = revision = 0; diff --git a/include/swift/Basic/Lazy.h b/include/swift/Basic/Lazy.h index 75a9e8643ca02..6b5ef60705e67 100644 --- a/include/swift/Basic/Lazy.h +++ b/include/swift/Basic/Lazy.h @@ -27,6 +27,14 @@ namespace swift { using OnceToken_t = dispatch_once_t; # define SWIFT_ONCE_F(TOKEN, FUNC, CONTEXT) \ ::dispatch_once_f(&TOKEN, CONTEXT, FUNC) +#elif defined(__CYGWIN__) + // _swift_once_f() is declared in Private.h. + // This prototype is copied instead including the header file. + void _swift_once_f(uintptr_t *predicate, void *context, + void (*function)(void *)); + using OnceToken_t = unsigned long; +# define SWIFT_ONCE_F(TOKEN, FUNC, CONTEXT) \ + _swift_once_f(&TOKEN, CONTEXT, FUNC) #else using OnceToken_t = std::once_flag; # define SWIFT_ONCE_F(TOKEN, FUNC, CONTEXT) \ diff --git a/include/swift/Runtime/HeapObject.h b/include/swift/Runtime/HeapObject.h index 3dc9b74ca63e8..e52c3b8439e11 100644 --- a/include/swift/Runtime/HeapObject.h +++ b/include/swift/Runtime/HeapObject.h @@ -87,8 +87,12 @@ struct TwoWordPair { // in registers, so cram the result into an unsigned long long. // Use an enum class with implicit conversions so we don't dirty C callers // too much. -#if __arm__ || __i386__ +#if __arm__ || __i386__ || defined(__CYGWIN__) +#if defined(__CYGWIN__) + enum class Return : unsigned __int128 {}; +#else enum class Return : unsigned long long {}; +#endif operator Return() const { union { diff --git a/include/swift/Runtime/Once.h b/include/swift/Runtime/Once.h index 24f5ca64f830e..50a187abeb3aa 100644 --- a/include/swift/Runtime/Once.h +++ b/include/swift/Runtime/Once.h @@ -27,6 +27,11 @@ namespace swift { // On OS X and iOS, swift_once_t matches dispatch_once_t. typedef long swift_once_t; +#elif defined(__CYGWIN__) + +// On Cygwin, std::once_flag can not be used because it is larger than the +// platform word. +typedef uintptr_t swift_once_t; #else // On other platforms swift_once_t is std::once_flag diff --git a/lib/Basic/Demangle.cpp b/lib/Basic/Demangle.cpp index 17851600a3df0..8892bae462567 100644 --- a/lib/Basic/Demangle.cpp +++ b/lib/Basic/Demangle.cpp @@ -23,6 +23,7 @@ #include "llvm/ADT/StringRef.h" #include #include +#include #include using namespace swift; diff --git a/lib/Basic/LangOptions.cpp b/lib/Basic/LangOptions.cpp index 0776f30d8cf49..e4a96aca2b6c9 100644 --- a/lib/Basic/LangOptions.cpp +++ b/lib/Basic/LangOptions.cpp @@ -29,7 +29,8 @@ static const StringRef SupportedConditionalCompilationOSs[] = { "watchOS", "iOS", "Linux", - "FreeBSD" + "FreeBSD", + "Windows" }; static const StringRef SupportedConditionalCompilationArches[] = { @@ -108,6 +109,8 @@ std::pair LangOptions::setTarget(llvm::Triple triple) { addPlatformConditionValue("os", "Linux"); else if (triple.isOSFreeBSD()) addPlatformConditionValue("os", "FreeBSD"); + else if (triple.isOSWindows()) + addPlatformConditionValue("os", "Windows"); else { UnsupportedOS = true; } diff --git a/lib/Basic/Platform.cpp b/lib/Basic/Platform.cpp index 2dcef79ec8f1f..1f6d200307cf8 100644 --- a/lib/Basic/Platform.cpp +++ b/lib/Basic/Platform.cpp @@ -66,6 +66,9 @@ StringRef swift::getPlatformNameForTriple(const llvm::Triple &triple) { if (triple.isOSFreeBSD()) return "freebsd"; + + if (triple.isOSWindows()) + return "windows"; return ""; } diff --git a/lib/Basic/Remangle.cpp b/lib/Basic/Remangle.cpp index a355bff03df98..02f1a2edc9e2c 100644 --- a/lib/Basic/Remangle.cpp +++ b/lib/Basic/Remangle.cpp @@ -24,6 +24,7 @@ #include "swift/Strings.h" #include "llvm/ADT/StringRef.h" #include +#include #include #include diff --git a/lib/Basic/TaskQueue.cpp b/lib/Basic/TaskQueue.cpp index cedd7ec98d971..0d1d0b067b819 100644 --- a/lib/Basic/TaskQueue.cpp +++ b/lib/Basic/TaskQueue.cpp @@ -23,7 +23,7 @@ using namespace swift; using namespace swift::sys; // Include the correct TaskQueue implementation. -#if LLVM_ON_UNIX +#if LLVM_ON_UNIX && !defined(__CYGWIN__) #include "Unix/TaskQueue.inc" #else #include "Default/TaskQueue.inc" diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 5d8c3240b2684..588791c25338b 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -2029,6 +2029,9 @@ const ToolChain *Driver::getToolChain(const ArgList &Args) const { case llvm::Triple::FreeBSD: TC = new toolchains::GenericUnix(*this, Target); break; + case llvm::Triple::Win32: + TC = new toolchains::Windows(*this, Target); + break; default: TC = nullptr; } diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index a31bdf3841fc0..003a817882045 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -1241,3 +1241,121 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job, return {"clang++", Arguments}; } +ToolChain::InvocationInfo +toolchains::Windows::constructInvocation(const InterpretJobAction &job, + const JobContext &context) const { + InvocationInfo II = ToolChain::constructInvocation(job, context); + + SmallString<128> runtimeLibraryPath; + getRuntimeLibraryPath(runtimeLibraryPath, context.Args, *this); + + addPathEnvironmentVariableIfNeeded(II.ExtraEnvironment, "LD_LIBRARY_PATH", + ":", options::OPT_L, context.Args, + runtimeLibraryPath); + return II; +} + +ToolChain::InvocationInfo +toolchains::Windows::constructInvocation(const AutolinkExtractJobAction &job, + const JobContext &context) const { + assert(context.Output.getPrimaryOutputType() == types::TY_AutolinkFile); + + ArgStringList Arguments; + addPrimaryInputsOfType(Arguments, context.Inputs, types::TY_Object); + addInputsOfType(Arguments, context.InputActions, types::TY_Object); + + Arguments.push_back("-o"); + Arguments.push_back( + context.Args.MakeArgString(context.Output.getPrimaryOutputFilename())); + + return {"swift-autolink-extract", Arguments}; +} + +ToolChain::InvocationInfo +toolchains::Windows::constructInvocation(const LinkJobAction &job, + const JobContext &context) const { + const Driver &D = getDriver(); + + assert(context.Output.getPrimaryOutputType() == types::TY_Image && + "Invalid linker output type."); + + ArgStringList Arguments; + + switch (job.getKind()) { + case LinkKind::None: + llvm_unreachable("invalid link kind"); + case LinkKind::Executable: + // Default case, nothing extra needed + break; + case LinkKind::DynamicLibrary: + Arguments.push_back("-shared"); + break; + } + + addPrimaryInputsOfType(Arguments, context.Inputs, types::TY_Object); + addInputsOfType(Arguments, context.InputActions, types::TY_Object); + + context.Args.AddAllArgs(Arguments, options::OPT_Xlinker); + context.Args.AddAllArgs(Arguments, options::OPT_linker_option_Group); + context.Args.AddAllArgs(Arguments, options::OPT_F); + + if (!context.OI.SDKPath.empty()) { + Arguments.push_back("--sysroot"); + Arguments.push_back(context.Args.MakeArgString(context.OI.SDKPath)); + } + + // Add the runtime library link path, which is platform-specific and found + // relative to the compiler. + // FIXME: Duplicated from CompilerInvocation, but in theory the runtime + // library link path and the standard library module import path don't + // need to be the same. + llvm::SmallString<128> RuntimeLibPath; + + if (const Arg *A = context.Args.getLastArg(options::OPT_resource_dir)) { + RuntimeLibPath = A->getValue(); + } else { + RuntimeLibPath = D.getSwiftProgramPath(); + llvm::sys::path::remove_filename(RuntimeLibPath); // remove /swift + llvm::sys::path::remove_filename(RuntimeLibPath); // remove /bin + llvm::sys::path::append(RuntimeLibPath, "lib", "swift"); + } + llvm::sys::path::append(RuntimeLibPath, + getPlatformNameForTriple(getTriple())); + Arguments.push_back("-L"); + Arguments.push_back(context.Args.MakeArgString(RuntimeLibPath)); + + if (context.Args.hasArg(options::OPT_profile_generate)) { + SmallString<128> LibProfile(RuntimeLibPath); + llvm::sys::path::remove_filename(LibProfile); // remove platform name + llvm::sys::path::append(LibProfile, "clang", CLANG_VERSION_STRING); + + llvm::sys::path::append(LibProfile, "lib", getTriple().getOSName(), + Twine("libclang_rt.profile-") + + getTriple().getArchName() + ".a"); + Arguments.push_back(context.Args.MakeArgString(LibProfile)); + } + + // FIXME: We probably shouldn't be adding an rpath here unless we know ahead + // of time the standard library won't be copied. + Arguments.push_back("-Xlinker"); + Arguments.push_back("-rpath"); + Arguments.push_back("-Xlinker"); + Arguments.push_back(context.Args.MakeArgString(RuntimeLibPath)); + + // Always add the stdlib + Arguments.push_back("-lswiftCore"); + + // Add any autolinking scripts to the arguments + for (const Job *Cmd : context.Inputs) { + auto &OutputInfo = Cmd->getOutput(); + if (OutputInfo.getPrimaryOutputType() == types::TY_AutolinkFile) + Arguments.push_back(context.Args.MakeArgString( + Twine("@") + OutputInfo.getPrimaryOutputFilename())); + } + + // This should be the last option, for convenience in checking output. + Arguments.push_back("-o"); + Arguments.push_back(context.Output.getPrimaryOutputFilename().c_str()); + + return {"clang++", Arguments}; +} diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index af186282c1e83..c0ca5648260fa 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -50,6 +50,20 @@ class LLVM_LIBRARY_VISIBILITY GenericUnix : public ToolChain { ~GenericUnix() = default; }; +class LLVM_LIBRARY_VISIBILITY Windows : public ToolChain { +protected: + InvocationInfo constructInvocation(const InterpretJobAction &job, + const JobContext &context) const override; + InvocationInfo constructInvocation(const AutolinkExtractJobAction &job, + const JobContext &context) const override; + InvocationInfo constructInvocation(const LinkJobAction &job, + const JobContext &context) const override; + +public: + Windows(const Driver &D, const llvm::Triple &Triple) : ToolChain(D, Triple) {} + ~Windows() = default; +}; + } // end namespace toolchains } // end namespace driver } // end namespace swift diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 659f2df602f3e..d75282d3dd8d7 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -835,7 +835,7 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, } if (UnsupportedOS) { - auto TargetArgOS = TargetComponents.size() > 2 ? TargetComponents.back() : ""; + auto TargetArgOS = TargetComponents.size() > 2 ? TargetComponents[2] : ""; Diags.diagnose(SourceLoc(), diag::error_unsupported_target_os, TargetArgOS); } diff --git a/lib/IDE/ReconstructType.cpp b/lib/IDE/ReconstructType.cpp index 0150c0df6846f..a468928758bb5 100644 --- a/lib/IDE/ReconstructType.cpp +++ b/lib/IDE/ReconstructType.cpp @@ -55,6 +55,8 @@ #include "swift/IDE/Utils.h" +#include + typedef const std::string ConstString; typedef void Log; typedef swift::ASTContext SwiftASTContext; diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp index 0dc688eabb268..85afb342900d1 100644 --- a/lib/IRGen/GenDecl.cpp +++ b/lib/IRGen/GenDecl.cpp @@ -2027,6 +2027,9 @@ llvm::Constant *IRGenModule::emitProtocolConformances() { case llvm::Triple::ELF: sectionName = ".swift2_protocol_conformances"; break; + case llvm::Triple::COFF: + sectionName = ".sw2prtc"; + break; default: llvm_unreachable("Don't know how to emit protocol conformances for " "the selected object format."); @@ -2108,6 +2111,9 @@ llvm::Constant *IRGenModule::emitTypeMetadataRecords() { case llvm::Triple::ELF: sectionName = ".swift2_type_metadata"; break; + case llvm::Triple::COFF: + sectionName = ".sw2tymd"; + break; default: llvm_unreachable("Don't know how to emit type metadata table for " "the selected object format."); diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp index 135a8f613b3f9..eec14ddcda3f7 100644 --- a/lib/IRGen/IRGenModule.cpp +++ b/lib/IRGen/IRGenModule.cpp @@ -97,7 +97,7 @@ static clang::CodeGenerator *createClangCodeGenerator(ASTContext &Context, } if (Opts.DebugInfoKind != IRGenDebugInfoKind::None) { CGO.DebugCompilationDir = Opts.DebugCompilationDir; - CGO.DwarfVersion = swift::DWARFVersion; + CGO.DwarfVersion = Opts.DWARFVersion; CGO.DwarfDebugFlags = Opts.DWARFDebugFlags; } @@ -751,6 +751,7 @@ void IRGenModule::emitAutolinkInfo() { } break; } + case llvm::Triple::COFF: case llvm::Triple::ELF: { // Merge the entries into null-separated string. llvm::SmallString<64> EntriesString; @@ -840,6 +841,7 @@ void IRGenModule::finalize() { ModuleHash->setSection("__LLVM,__swift_modhash"); break; case llvm::Triple::ELF: + case llvm::Triple::COFF: ModuleHash->setSection(".swift_modhash"); break; default: diff --git a/lib/SIL/Projection.cpp b/lib/SIL/Projection.cpp index 275faaaf09f32..e9f2ec388bb2d 100644 --- a/lib/SIL/Projection.cpp +++ b/lib/SIL/Projection.cpp @@ -1472,12 +1472,12 @@ replaceValueUsesWithLeafUses(SILBuilder &Builder, SILLocation Loc, DEBUG(llvm::dbgs() << " Current Worklist:\n"); #ifndef NDEBUG - for (auto *_N : Worklist) { - DEBUG(llvm::dbgs() << " Type: " << _N->getType() + for (auto *_work : Worklist) { + DEBUG(llvm::dbgs() << " Type: " << _work->getType() << "; Complete: " - << (AggBuilderMap.isComplete(_N)? "yes" : "no") + << (AggBuilderMap.isComplete(_work)? "yes" : "no") << "; Invalidated: " - << (AggBuilderMap.isInvalidated(_N)? "yes" : "no") << "\n"); + << (AggBuilderMap.isInvalidated(_work)? "yes" : "no") << "\n"); } #endif diff --git a/lib/Sema/PlaygroundTransform.cpp b/lib/Sema/PlaygroundTransform.cpp index 39181846b4304..483af044cace6 100644 --- a/lib/Sema/PlaygroundTransform.cpp +++ b/lib/Sema/PlaygroundTransform.cpp @@ -29,6 +29,7 @@ #include "swift/Subsystems.h" #include "TypeChecker.h" +#include #include #include diff --git a/stdlib/public/CMakeLists.txt b/stdlib/public/CMakeLists.txt index f1422e02c591e..b22429327b235 100644 --- a/stdlib/public/CMakeLists.txt +++ b/stdlib/public/CMakeLists.txt @@ -2,6 +2,10 @@ # introducing static constructors or destructors. set(SWIFT_CORE_CXX_FLAGS) +if(CMAKE_SYSTEM_NAME STREQUAL "CYGWIN") + list(APPEND SWIFT_CORE_CXX_FLAGS "-mcmodel=large") +endif() + check_cxx_compiler_flag("-Werror -Wglobal-constructors" CXX_SUPPORTS_GLOBAL_CONSTRUCTORS_WARNING) if(CXX_SUPPORTS_GLOBAL_CONSTRUCTORS_WARNING) list(APPEND SWIFT_CORE_CXX_FLAGS "-Wglobal-constructors") diff --git a/stdlib/public/SwiftShims/Visibility.h b/stdlib/public/SwiftShims/Visibility.h index 2844b8059773f..20d87b07b9012 100644 --- a/stdlib/public/SwiftShims/Visibility.h +++ b/stdlib/public/SwiftShims/Visibility.h @@ -27,6 +27,8 @@ // valid in ELF shared objects, and leaving them relocatable at load time // defeats the purpose of the relative references. # define SWIFT_RUNTIME_EXPORT __attribute__((visibility("protected"))) +#elif __CYGWIN__ +# define SWIFT_RUNTIME_EXPORT #else // __dllexport/__dllimport for Windows? # error "Unimplemented object format" diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt index ab4e85f50da57..e304c35e01db2 100644 --- a/stdlib/public/core/CMakeLists.txt +++ b/stdlib/public/core/CMakeLists.txt @@ -161,6 +161,13 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux") ${BSD_LIBRARIES}) endif() +if(CMAKE_SYSTEM_NAME STREQUAL "CYGWIN") + execute_process(COMMAND "cygpath" "-u" "$ENV{SYSTEMROOT}" + OUTPUT_VARIABLE ENV_SYSTEMROOT) + + list(APPEND swift_core_link_flags "${ENV_SYSTEMROOT}/system32/psapi.dll") +endif() + option(SWIFT_CHECK_ESSENTIAL_STDLIB "Check core standard library layering by linking its essential subset" FALSE) diff --git a/stdlib/public/core/Print.swift b/stdlib/public/core/Print.swift index 65a5fb02d8e71..60f7ae2f01160 100644 --- a/stdlib/public/core/Print.swift +++ b/stdlib/public/core/Print.swift @@ -28,6 +28,11 @@ public func print( separator: String = " ", terminator: String = "\n" ) { +#if os(Windows) + // FIXME: This fix is for 'crash at hook(output.left)' in cygwin. + // Proper fix is needed. see: https://bugs.swift.org/browse/SR-612 + let _playgroundPrintHook: ((String)->Void)? = nil +#endif if let hook = _playgroundPrintHook { var output = _TeeStream(left: "", right: _Stdout()) _print( diff --git a/stdlib/public/runtime/CMakeLists.txt b/stdlib/public/runtime/CMakeLists.txt index c685bfb316ceb..39444d51d0df4 100644 --- a/stdlib/public/runtime/CMakeLists.txt +++ b/stdlib/public/runtime/CMakeLists.txt @@ -17,11 +17,12 @@ if(SWIFT_RUNTIME_ENABLE_LEAK_CHECKER) set(swift_runtime_leaks_sources Leaks.mm) endif() -# Acknowledge that the following sources are known. -set(LLVM_OPTIONAL_SOURCES - Remangle.cpp - swift_sections.S) - +set(swift_runtime_port_sources) +if("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN") + set(swift_runtime_port_sources + CygwinPort.cpp) +endif() + set(swift_runtime_objc_sources) set(swift_runtime_unicode_normalization_sources) if(SWIFT_HOST_VARIANT MATCHES "${SWIFT_DARWIN_VARIANTS}") @@ -49,19 +50,23 @@ set(swift_runtime_sources Reflection.cpp SwiftObject.cpp) +# Acknowledge that the following sources are known. +set(LLVM_OPTIONAL_SOURCES + Remangle.cpp + swift_sections.S + CygwinPort.cpp + ${swift_runtime_sources} + ${swift_runtime_objc_sources} + ${swift_runtime_leaks_sources}) + add_swift_library(swiftRuntime IS_STDLIB IS_STDLIB_CORE ${swift_runtime_sources} ${swift_runtime_objc_sources} ${swift_runtime_leaks_sources} + ${swift_runtime_port_sources} C_COMPILE_FLAGS ${swift_runtime_compile_flags} INSTALL_IN_COMPONENT stdlib) -set(LLVM_OPTIONAL_SOURCES - Remangle.cpp - ${swift_runtime_sources} - ${swift_runtime_objc_sources} - ${swift_runtime_leaks_sources}) - if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") add_swift_library(section_magic_begin IS_STDLIB IS_STDLIB_CORE swift_sections.S diff --git a/stdlib/public/runtime/CygwinPort.cpp b/stdlib/public/runtime/CygwinPort.cpp new file mode 100644 index 0000000000000..8df33d108f355 --- /dev/null +++ b/stdlib/public/runtime/CygwinPort.cpp @@ -0,0 +1,148 @@ +//===--- CygwinPort.cpp - Functions for Cygwin port ----===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// Implementations Cygwin specific functions needed for running Swift. +// +//===----------------------------------------------------------------------===// + +#include "Private.h" +#include "swift/Runtime/Debug.h" +#include +#include +#include +#include +#include +#include +#include + +using namespace swift; + +static std::mutex swiftOnceMutex; + +int swift::_swift_dl_iterate_phdr(int (*Callback)(struct dl_phdr_info *info, + size_t size, void *data), + void *data) { + DWORD procId = GetCurrentProcessId(); + HANDLE procHandle = + OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, procId); + if (!procHandle) { + swift::fatalError(/* flags = */ 0, "OpenProcess() failed"); + return 0; + } + + int lastRet = 0; + + std::vector modules(1024); + DWORD neededSize; + + BOOL ret = EnumProcessModules(procHandle, modules.data(), + modules.size() * sizeof(HMODULE), &neededSize); + + if (ret == FALSE) { + swift::fatalError(/* flags = */ 0, "EnumProcessModules() failed"); + return 0; + } + + if (modules.size() * sizeof(HMODULE) < neededSize) { + modules.resize(neededSize / sizeof(HMODULE)); + ret = EnumProcessModules(procHandle, modules.data(), + modules.size() * sizeof(HMODULE), &neededSize); + } + + if (ret == FALSE) { + swift::fatalError(/* flags = */ 0, "EnumProcessModules() failed"); + return 0; + } + + for (unsigned int i = 0; i < neededSize / sizeof(HMODULE); i++) { + char modName[MAX_PATH]; + + if (!GetModuleFileNameExA(procHandle, modules[i], modName, + sizeof(modName))) { + swift::fatalError(/* flags = */ 0, "GetModuleFileNameExA() failed"); + } + + dl_phdr_info hdr; + hdr.dlpi_name = modName; + hdr.dlpi_addr = modules[i]; + + lastRet = Callback(&hdr, sizeof(hdr), data); + if (lastRet != 0) + break; + } + + CloseHandle(procHandle); + + return lastRet; +} + +uint8_t *swift::_swift_getSectionDataPE(void *handle, const char *sectionName, + unsigned long *sectionSize) { + // In Cygwin, dlopen() returns PE/COFF image pointer. + // This is relying on undocumented feature of Windows API LoadLibrary(). + unsigned char *peStart = (unsigned char *)handle; + + int ntHeadersOffset = peStart[0x3C]; + + bool assert1 = + peStart[ntHeadersOffset] == 'P' && peStart[ntHeadersOffset + 1] == 'E'; + if (assert1 == false) { + swift::fatalError(/* flags = */ 0, "_swift_getSectionDataPE()'s finding PE failed"); + } + + unsigned char *coff = peStart + ntHeadersOffset + 4; + + int16_t numberOfSections = *(int16_t *)(coff + 2); + + // SizeOfOptionalHeader + int16_t sizeOfOptionalHeader = *(int16_t *)(coff + 16); + + const int kCoffFileHeaderSize = 20; + unsigned char *sectionTableBase = + coff + kCoffFileHeaderSize + sizeOfOptionalHeader; + + // Section Header Record + const int kSectionRecordSize = 40; + + unsigned char *sectionHeader = sectionTableBase; + for (int i = 0; i < numberOfSections; i++) { + uint32_t virtualSize = *(uint32_t *)§ionHeader[8]; + uint32_t virtualAddress = *(uint32_t *)§ionHeader[12]; + + char nameOfThisSection[9]; + memcpy(nameOfThisSection, sectionHeader, 8); + nameOfThisSection[8] = '\0'; + + if (strcmp(sectionName, nameOfThisSection) == 0) { + *sectionSize = virtualSize; + return (uint8_t *)handle + virtualAddress; + } + sectionHeader += kSectionRecordSize; + } + + return nullptr; +} + +void swift::_swift_once_f(uintptr_t *predicate, void *context, + void (*function)(void *)) { + // FIXME: This implementation does a global lock, which is much worse than + // what we have on other platforms. Each swift_once should synchronize on the + // token. + swiftOnceMutex.lock(); + if (*predicate == 0) { + *predicate = 1ul; + swiftOnceMutex.unlock(); + + function(context); + } else + swiftOnceMutex.unlock(); +} diff --git a/stdlib/public/runtime/Errors.cpp b/stdlib/public/runtime/Errors.cpp index bbedfc575eb3e..e3dfdec4c0d27 100644 --- a/stdlib/public/runtime/Errors.cpp +++ b/stdlib/public/runtime/Errors.cpp @@ -24,7 +24,9 @@ #include "swift/Runtime/Debug.h" #include "swift/Basic/Demangle.h" #include +#if !defined(__CYGWIN__) #include +#endif #ifdef __APPLE__ #include @@ -36,6 +38,7 @@ enum: uint32_t { }; } // end namespace FatalErrorFlags +#if !defined(__CYGWIN__) LLVM_ATTRIBUTE_ALWAYS_INLINE static bool isIdentifier(char c) @@ -141,7 +144,7 @@ reportBacktrace(int *count) return symbols; } - +#endif #ifdef SWIFT_HAVE_CRASHREPORTERCLIENT #include @@ -199,6 +202,7 @@ reportNow(uint32_t flags, const char *message) #ifdef __APPLE__ asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s", message); #endif +#if !defined(__CYGWIN__) if (flags & FatalErrorFlags::ReportBacktrace) { fputs("Current stack trace:\n", stderr); int count = 0; @@ -208,6 +212,7 @@ reportNow(uint32_t flags, const char *message) } free(trace); } +#endif } /// Report a fatal error to system console, stderr, and crash logs. diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp index da1bcedad2f2a..ed38af65d37a5 100644 --- a/stdlib/public/runtime/Metadata.cpp +++ b/stdlib/public/runtime/Metadata.cpp @@ -45,6 +45,8 @@ #include #endif +#include + #if defined(__APPLE__) && defined(VM_MEMORY_SWIFT_METADATA) #define VM_TAG_FOR_SWIFT_METADATA VM_MAKE_TAG(VM_MEMORY_SWIFT_METADATA) #else diff --git a/stdlib/public/runtime/MetadataLookup.cpp b/stdlib/public/runtime/MetadataLookup.cpp index 2dfbb4d4935e3..6bce8e595fbcb 100644 --- a/stdlib/public/runtime/MetadataLookup.cpp +++ b/stdlib/public/runtime/MetadataLookup.cpp @@ -49,6 +49,8 @@ using namespace Demangle; #define SWIFT_TYPE_METADATA_SECTION "__swift2_types" #elif defined(__ELF__) #define SWIFT_TYPE_METADATA_SECTION ".swift2_type_metadata_start" +#elif defined(__CYGWIN__) +#define SWIFT_TYPE_METADATA_SECTION ".sw2tymd" #endif // Type Metadata Cache. @@ -176,6 +178,26 @@ static int _addImageTypeMetadataRecords(struct dl_phdr_info *info, dlclose(handle); return 0; } +#elif defined(__CYGWIN__) +static int _addImageTypeMetadataRecords(struct dl_phdr_info *info, + size_t size, void * /*data*/) { + void *handle; + if (!info->dlpi_name || info->dlpi_name[0] == '\0') { + handle = dlopen(nullptr, RTLD_LAZY); + } else + handle = dlopen(info->dlpi_name, RTLD_LAZY | RTLD_NOLOAD); + + unsigned long recordsSize; + const uint8_t *records = + _swift_getSectionDataPE(handle, SWIFT_TYPE_METADATA_SECTION, + &recordsSize); + + if (records) { + _addImageTypeMetadataRecordsBlock(records, recordsSize); + } + dlclose(handle); + return 0; +} #endif static void _initializeCallbacksToInspectDylib() { @@ -190,6 +212,8 @@ static void _initializeCallbacksToInspectDylib() { // FIXME: Find a way to have this continue to happen after. // rdar://problem/19045112 dl_iterate_phdr(_addImageTypeMetadataRecords, nullptr); +#elif defined(__CYGWIN__) + _swift_dl_iterate_phdr(_addImageTypeMetadataRecords, nullptr); #else # error No known mechanism to inspect dynamic libraries on this platform. #endif diff --git a/stdlib/public/runtime/Once.cpp b/stdlib/public/runtime/Once.cpp index 5fea28dd1ab66..fe33b3a44c4be 100644 --- a/stdlib/public/runtime/Once.cpp +++ b/stdlib/public/runtime/Once.cpp @@ -14,6 +14,7 @@ // //===----------------------------------------------------------------------===// +#include "Private.h" #include "swift/Runtime/Once.h" #include "swift/Runtime/Debug.h" #include @@ -40,6 +41,8 @@ static_assert(sizeof(swift_once_t) <= sizeof(void*), void swift::swift_once(swift_once_t *predicate, void (*fn)(void *)) { #if defined(__APPLE__) dispatch_once_f(predicate, nullptr, fn); +#elif defined(__CYGWIN__) + _swift_once_f(predicate, nullptr, fn); #else // FIXME: We're relying here on the coincidence that libstdc++ uses pthread's // pthread_once, and that on glibc pthread_once follows a compatible init diff --git a/stdlib/public/runtime/Private.h b/stdlib/public/runtime/Private.h index 214cd6cfd055f..d817abe0f1ee6 100644 --- a/stdlib/public/runtime/Private.h +++ b/stdlib/public/runtime/Private.h @@ -124,6 +124,21 @@ namespace swift { Demangle::NodePointer _swift_buildDemanglingForMetadata(const Metadata *type); #endif +#if defined(__CYGWIN__) + struct dl_phdr_info { + void *dlpi_addr; + const char *dlpi_name; + }; + + int _swift_dl_iterate_phdr(int (*Callback)(struct dl_phdr_info *info, + size_t size, void *data), + void *data); + uint8_t *_swift_getSectionDataPE(void *handle, const char *sectionName, + unsigned long *sectionSize); + void _swift_once_f(uintptr_t *predicate, void *context, + void (*function)(void *)); +#endif + } // end namespace swift #endif /* SWIFT_RUNTIME_PRIVATE_H */ diff --git a/stdlib/public/runtime/ProtocolConformance.cpp b/stdlib/public/runtime/ProtocolConformance.cpp index 8d4447a2a68e5..bfb273699b6c0 100644 --- a/stdlib/public/runtime/ProtocolConformance.cpp +++ b/stdlib/public/runtime/ProtocolConformance.cpp @@ -33,7 +33,6 @@ using namespace swift; - #if !defined(NDEBUG) && SWIFT_OBJC_INTEROP #include @@ -143,6 +142,8 @@ const { #define SWIFT_PROTOCOL_CONFORMANCES_SECTION "__swift2_proto" #elif defined(__ELF__) #define SWIFT_PROTOCOL_CONFORMANCES_SECTION ".swift2_protocol_conformances_start" +#elif defined(__CYGWIN__) +#define SWIFT_PROTOCOL_CONFORMANCES_SECTION ".sw2prtc" #endif namespace { @@ -181,7 +182,7 @@ namespace { # if __APPLE__ assert((!Success && Data <= 0xFFFFFFFFU) || (Success && Data > 0xFFFFFFFFU)); -# elif __linux__ || __FreeBSD__ +# elif __linux__ || __FreeBSD__ || __CYGWIN__ assert((!Success && Data <= 0x0FFFU) || (Success && Data > 0x0FFFU)); # else @@ -216,7 +217,7 @@ namespace { #if __LP64__ # if __APPLE__ return Data > 0xFFFFFFFFU; -# elif __linux__ || __FreeBSD__ +# elif __linux__ || __FreeBSD__ || __CYGWIN__ return Data > 0x0FFFU; # else # error "port me" @@ -332,6 +333,31 @@ static int _addImageProtocolConformances(struct dl_phdr_info *info, dlclose(handle); return 0; } +#elif defined(__CYGWIN__) +static int _addImageProtocolConformances(struct dl_phdr_info *info, + size_t size, void * /*data*/) { + void *handle; + if (!info->dlpi_name || info->dlpi_name[0] == '\0') { + handle = dlopen(nullptr, RTLD_LAZY); + } else + handle = dlopen(info->dlpi_name, RTLD_LAZY | RTLD_NOLOAD); + + unsigned long conformancesSize; + const uint8_t *conformances = + _swift_getSectionDataPE(handle, SWIFT_PROTOCOL_CONFORMANCES_SECTION, + &conformancesSize); + + if (!conformances) { + // if there are no conformances, don't hold this handle open. + dlclose(handle); + return 0; + } + + _addImageProtocolConformancesBlock(conformances, conformancesSize); + + dlclose(handle); + return 0; +} #endif static void _initializeCallbacksToInspectDylib() { @@ -346,6 +372,8 @@ static void _initializeCallbacksToInspectDylib() { // FIXME: Find a way to have this continue to happen after. // rdar://problem/19045112 dl_iterate_phdr(_addImageProtocolConformances, nullptr); +#elif defined(__CYGWIN__) + _swift_dl_iterate_phdr(_addImageProtocolConformances, nullptr); #else # error No known mechanism to inspect dynamic libraries on this platform. #endif diff --git a/stdlib/public/runtime/Reflection.mm b/stdlib/public/runtime/Reflection.mm index 4e9a6e9af86c0..3b59071363237 100644 --- a/stdlib/public/runtime/Reflection.mm +++ b/stdlib/public/runtime/Reflection.mm @@ -19,6 +19,7 @@ #include "swift/Runtime/Debug.h" #include "Private.h" #include +#include #include #include #include diff --git a/stdlib/public/stubs/LibcShims.cpp b/stdlib/public/stubs/LibcShims.cpp index 57bc8c770a5b1..353d810eb22f0 100644 --- a/stdlib/public/stubs/LibcShims.cpp +++ b/stdlib/public/stubs/LibcShims.cpp @@ -50,7 +50,7 @@ int _swift_stdlib_close(int fd) { return close(fd); } #if defined(__APPLE__) #include size_t _swift_stdlib_malloc_size(const void *ptr) { return malloc_size(ptr); } -#elif defined(__GNU_LIBRARY__) +#elif defined(__GNU_LIBRARY__) || defined(__CYGWIN__) #include size_t _swift_stdlib_malloc_size(const void *ptr) { return malloc_usable_size(const_cast(ptr)); diff --git a/stdlib/public/stubs/Stubs.cpp b/stdlib/public/stubs/Stubs.cpp index 7c09067720c84..13a140afcaa4f 100644 --- a/stdlib/public/stubs/Stubs.cpp +++ b/stdlib/public/stubs/Stubs.cpp @@ -29,7 +29,13 @@ #include #include #include +#if defined(__CYGWIN__) +#include +#include +#define fmodl(lhs, rhs) std::fmod(lhs, rhs) +#else #include +#endif #include #include "llvm/ADT/StringExtras.h" #include "swift/Runtime/Debug.h" @@ -106,6 +112,8 @@ static inline locale_t getCLocale() { // as C locale. return nullptr; } +#elif defined(__CYGWIN__) +// In Cygwin, getCLocale() is not used. #else static locale_t makeCLocale() { locale_t CLocale = newlocale(LC_ALL_MASK, "C", nullptr); @@ -122,6 +130,8 @@ static locale_t getCLocale() { #if defined(__APPLE__) #define swift_snprintf_l snprintf_l +#elif defined(__CYGWIN__) +// In Cygwin, swift_snprintf_l() is not used. #else static int swift_snprintf_l(char *Str, size_t StrSize, locale_t Locale, const char *Format, ...) { @@ -153,6 +163,24 @@ static uint64_t swift_floatingPointToString(char *Buffer, size_t BufferLength, Precision = std::numeric_limits::max_digits10; } +#if defined(__CYGWIN__) + // Cygwin does not support uselocale(), but we can use the locale feature + // in stringstream object. + std::ostringstream ValueStream; + ValueStream.width(0); + ValueStream.precision(Precision); + ValueStream.imbue(std::locale::classic()); + ValueStream << Value; + std::string ValueString(ValueStream.str()); + size_t i = ValueString.length(); + + if (i < BufferLength) { + std::copy(ValueString.begin(), ValueString.end(), Buffer); + Buffer[i] = '\0'; + } else { + swift::crash("swift_floatingPointToString: insufficient buffer size"); + } +#else // Pass a null locale to use the C locale. int i = swift_snprintf_l(Buffer, BufferLength, /*locale=*/nullptr, Format, Precision, Value); @@ -162,6 +190,7 @@ static uint64_t swift_floatingPointToString(char *Buffer, size_t BufferLength, "swift_floatingPointToString: unexpected return value from sprintf"); if (size_t(i) >= BufferLength) swift::crash("swift_floatingPointToString: insufficient buffer size"); +#endif // Add ".0" to a float that (a) is not in scientific notation, (b) does not // already have a fractional part, (c) is not infinite, and (d) is not a NaN @@ -327,6 +356,42 @@ __mulodi4(di_int a, di_int b, int* overflow) } #endif +#if defined(__CYGWIN__) +// Cygwin does not support uselocale(), but we can use the locale feature +// in stringstream object. +template +static const char *_swift_stdlib_strtoX_clocale_impl( + const char *nptr, T *outResult) { + std::istringstream ValueStream(nptr); + ValueStream.imbue(std::locale::classic()); + T ParsedValue; + ValueStream >> ParsedValue; + *outResult = ParsedValue; + + int pos = ValueStream.tellg(); + if (pos <= 0) + return nullptr; + + return nptr + pos; +} + +extern "C" const char *_swift_stdlib_strtold_clocale( + const char *nptr, void *outResult) { + return _swift_stdlib_strtoX_clocale_impl( + nptr, static_cast(outResult)); +} + +extern "C" const char *_swift_stdlib_strtod_clocale( + const char * nptr, double *outResult) { + return _swift_stdlib_strtoX_clocale_impl(nptr, outResult); +} + +extern "C" const char *_swift_stdlib_strtof_clocale( + const char * nptr, float *outResult) { + return _swift_stdlib_strtoX_clocale_impl(nptr, outResult); +} +#else + // We can't return Float80, but we can receive a pointer to one, so // switch the return type and the out parameter on strtold. template @@ -365,6 +430,7 @@ extern "C" const char *_swift_stdlib_strtof_clocale( return _swift_stdlib_strtoX_clocale_impl( nptr, outResult, HUGE_VALF, strtof_l); } +#endif SWIFT_RUNTIME_STDLIB_INTERFACE extern "C" void _swift_stdlib_flockfile_stdout() { diff --git a/stdlib/public/stubs/UnicodeNormalization.cpp b/stdlib/public/stubs/UnicodeNormalization.cpp index 32c8ea938ac28..b3332bbd0a3b8 100644 --- a/stdlib/public/stubs/UnicodeNormalization.cpp +++ b/stdlib/public/stubs/UnicodeNormalization.cpp @@ -91,7 +91,11 @@ class ASCIICollation { for (unsigned char c = 0; c < 128; ++c) { UErrorCode ErrorCode = U_ZERO_ERROR; intptr_t NumCollationElts = 0; +#if defined(__CYGWIN__) + UChar Buffer[1]; +#else uint16_t Buffer[1]; +#endif Buffer[0] = c; UCollationElements *CollationIterator = @@ -129,9 +133,18 @@ int32_t _swift_stdlib_unicode_compare_utf16_utf16(const uint16_t *LeftString, int32_t LeftLength, const uint16_t *RightString, int32_t RightLength) { +#if defined(__CYGWIN__) + // ICU UChar type is platform dependent. In Cygwin, it is defined + // as wchar_t which size is 2. It seems that the underlying binary + // representation is same with swift utf16 representation. + return ucol_strcoll(GetRootCollator(), + reinterpret_cast(LeftString), LeftLength, + reinterpret_cast(RightString), RightLength); +#else return ucol_strcoll(GetRootCollator(), LeftString, LeftLength, RightString, RightLength); +#endif } /// Compares the strings via the Unicode Collation Algorithm on the root locale. @@ -150,7 +163,12 @@ int32_t _swift_stdlib_unicode_compare_utf8_utf16(const char *LeftString, UErrorCode ErrorCode = U_ZERO_ERROR; uiter_setUTF8(&LeftIterator, LeftString, LeftLength); +#if defined(__CYGWIN__) + uiter_setString(&RightIterator, reinterpret_cast(RightString), + RightLength); +#else uiter_setString(&RightIterator, RightString, RightLength); +#endif uint32_t Diff = ucol_strcollIter(GetRootCollator(), &LeftIterator, &RightIterator, &ErrorCode); @@ -203,8 +221,13 @@ int32_t _swift_stdlib_unicode_compare_utf8_utf8(const char *LeftString, static intptr_t hashChunk(const UCollator *Collator, intptr_t HashState, const uint16_t *Str, uint32_t Length, UErrorCode *ErrorCode) { +#if defined(__CYGWIN__) + UCollationElements *CollationIterator = ucol_openElements( + Collator, reinterpret_cast(Str), Length, ErrorCode); +#else UCollationElements *CollationIterator = ucol_openElements( Collator, Str, Length, ErrorCode); +#endif while (U_SUCCESS(*ErrorCode)) { intptr_t Elem = ucol_next(CollationIterator, ErrorCode); // Ignore zero valued collation elements. They don't participate in the @@ -281,9 +304,17 @@ int32_t _swift_stdlib_unicode_strToUpper(uint16_t *Destination, const uint16_t *Source, int32_t SourceLength) { UErrorCode ErrorCode = U_ZERO_ERROR; +#if defined(__CYGWIN__) + uint32_t OutputLength = u_strToUpper(reinterpret_cast(Destination), + DestinationCapacity, + reinterpret_cast(Source), + SourceLength, + "", &ErrorCode); +#else uint32_t OutputLength = u_strToUpper(Destination, DestinationCapacity, Source, SourceLength, "", &ErrorCode); +#endif if (U_FAILURE(ErrorCode) && ErrorCode != U_BUFFER_OVERFLOW_ERROR) { swift::crash("u_strToUpper: Unexpected error uppercasing unicode string."); } @@ -301,9 +332,17 @@ int32_t _swift_stdlib_unicode_strToLower(uint16_t *Destination, const uint16_t *Source, int32_t SourceLength) { UErrorCode ErrorCode = U_ZERO_ERROR; +#if defined(__CYGWIN__) + uint32_t OutputLength = u_strToLower(reinterpret_cast(Destination), + DestinationCapacity, + reinterpret_cast(Source), + SourceLength, + "", &ErrorCode); +#else uint32_t OutputLength = u_strToLower(Destination, DestinationCapacity, Source, SourceLength, "", &ErrorCode); +#endif if (U_FAILURE(ErrorCode) && ErrorCode != U_BUFFER_OVERFLOW_ERROR) { swift::crash("u_strToLower: Unexpected error lowercasing unicode string."); } diff --git a/test/BuildConfigurations/x64WindowsTarget.swift b/test/BuildConfigurations/x64WindowsTarget.swift new file mode 100644 index 0000000000000..b4bd7d590eaa7 --- /dev/null +++ b/test/BuildConfigurations/x64WindowsTarget.swift @@ -0,0 +1,8 @@ +// RUN: %swift -parse %s -verify -D FOO -D BAR -target x86_64-unknown-windows-cygnus -disable-objc-interop -D FOO -parse-stdlib +// RUN: %swift-ide-test -test-input-complete -source-filename=%s -target x86_64-unknown-windows-cygnus + +#if arch(x86_64) && os(Windows) && _runtime(_Native) +class C {} +var x = C() +#endif +var y = x diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 147bc10ff44b2..3e117930bed9f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -57,6 +57,7 @@ function(get_test_dependencies SDK result_var_name) ("${SDK}" STREQUAL "TVOS_SIMULATOR") OR ("${SDK}" STREQUAL "WATCHOS_SIMULATOR") OR ("${SDK}" STREQUAL "LINUX") OR + ("${SDK}" STREQUAL "CYGWIN") OR ("${SDK}" STREQUAL "FREEBSD")) # No extra dependencies. else() diff --git a/tools/driver/frontend_main.cpp b/tools/driver/frontend_main.cpp index ce9a535664748..61c2f1d994c1b 100644 --- a/tools/driver/frontend_main.cpp +++ b/tools/driver/frontend_main.cpp @@ -25,6 +25,7 @@ #include "swift/AST/NameLookup.h" #include "swift/AST/ReferencedNameTracker.h" #include "swift/AST/TypeRefinementContext.h" +#include "swift/Basic/Dwarf.h" #include "swift/Basic/Fallthrough.h" #include "swift/Basic/FileSystem.h" #include "swift/Basic/SourceManager.h" @@ -1019,6 +1020,12 @@ int frontend_main(ArrayRefArgs, return 1; } + // Setting DWARF Version depend on platform + IRGenOptions &IRGenOpts = Invocation.getIRGenOptions(); + IRGenOpts.DWARFVersion = swift::GenericDWARFVersion; + if (Invocation.getLangOptions().Target.isWindowsCygwinEnvironment()) + IRGenOpts.DWARFVersion = swift::CygwinDWARFVersion; + if (Invocation.getFrontendOptions().PrintHelp || Invocation.getFrontendOptions().PrintHelpHidden) { unsigned IncludedFlagsBitmask = options::FrontendOption; diff --git a/tools/sil-extract/SILExtract.cpp b/tools/sil-extract/SILExtract.cpp index 22c5fd383765a..bd91fb82291c4 100644 --- a/tools/sil-extract/SILExtract.cpp +++ b/tools/sil-extract/SILExtract.cpp @@ -36,6 +36,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/Signals.h" +#include using namespace swift; static llvm::cl::opt diff --git a/tools/sil-opt/SILOpt.cpp b/tools/sil-opt/SILOpt.cpp index 0af50e7aa75ab..4e7e534ce474d 100644 --- a/tools/sil-opt/SILOpt.cpp +++ b/tools/sil-opt/SILOpt.cpp @@ -37,6 +37,7 @@ #include "llvm/Support/Path.h" #include "llvm/Support/Signals.h" #include "llvm/Support/TargetSelect.h" +#include using namespace swift; namespace { diff --git a/tools/swift-demangle/swift-demangle.cpp b/tools/swift-demangle/swift-demangle.cpp index 63196d6c5bc18..3d0e66ab82a71 100644 --- a/tools/swift-demangle/swift-demangle.cpp +++ b/tools/swift-demangle/swift-demangle.cpp @@ -22,6 +22,7 @@ #include "llvm/Support/Signals.h" #include "llvm/Support/raw_ostream.h" +#include #include static llvm::cl::opt @@ -96,6 +97,11 @@ static llvm::StringRef substrAfter(llvm::StringRef whole, } int main(int argc, char **argv) { +#if defined(__CYGWIN__) + // Cygwin clang 3.5.2 with '-O3' generates CRASHING BINARY, + // if main()'s first function call is passing argv[0]. + std::rand(); +#endif llvm::cl::ParseCommandLineOptions(argc, argv); swift::Demangle::DemangleOptions options; diff --git a/utils/build-script-impl b/utils/build-script-impl index 02654daf79c1f..3db1a51d55d95 100755 --- a/utils/build-script-impl +++ b/utils/build-script-impl @@ -247,6 +247,9 @@ function set_deployment_target_based_options() { linux-powerpc64le) SWIFT_HOST_VARIANT_ARCH="powerpc64le" ;; + cygwin-x86_64) + SWIFT_HOST_VARIANT_ARCH="x86_64" + ;; macosx-* | iphoneos-* | iphonesimulator-* | \ appletvos-* | appletvsimulator-* | \ watchos-* | watchsimulator-*) @@ -802,6 +805,12 @@ case "$(uname -s -m)" in ) ;; + CYGWIN_NT-10.0\ x86_64) + STDLIB_DEPLOYMENT_TARGETS=( + "cygwin-x86_64" + ) + ;; + *) echo "Unknown operating system" exit 1 @@ -904,6 +913,10 @@ for deployment_target in "${STDLIB_DEPLOYMENT_TARGETS[@]}"; do build_for_this_target=1 test_this_target=1 ;; + cygwin-*) + build_for_this_target=1 + test_this_target=1 + ;; macosx-*) build_for_this_target=$(not ${SKIP_BUILD_OSX}) test_this_target=$(not ${SKIP_TEST_OSX}) @@ -1688,6 +1701,24 @@ for deployment_target in "${HOST_TARGET}" "${CROSS_TOOLS_DEPLOYMENT_TARGETS[@]}" "${LLDB_SOURCE_DIR}" ) ;; + CYGWIN_NT-10.0) + cmake_options=( + "${cmake_options[@]}" + -DCMAKE_BUILD_TYPE:STRING="${LLDB_BUILD_TYPE}" + -DCMAKE_INSTALL_PREFIX:PATH="${INSTALL_PREFIX}" + -DLLDB_PATH_TO_LLVM_SOURCE:PATH="${LLVM_SOURCE_DIR}" + -DLLDB_PATH_TO_CLANG_SOURCE:PATH="${CLANG_SOURCE_DIR}" + -DLLDB_PATH_TO_SWIFT_SOURCE:PATH="${SWIFT_SOURCE_DIR}" + -DLLDB_PATH_TO_LLVM_BUILD:PATH="${llvm_build_dir}" + -DLLDB_PATH_TO_CLANG_BUILD:PATH="${llvm_build_dir}" + -DLLDB_PATH_TO_SWIFT_BUILD:PATH="${swift_build_dir}" + -DLLDB_PATH_TO_CMARK_BUILD:PATH="${cmark_build_dir}" + -DLLDB_IS_BUILDBOT_BUILD="${LLDB_IS_BUILDBOT_BUILD}" + -DLLDB_BUILD_DATE:STRING="\"${LLDB_BUILD_DATE}\"" + -DLLDB_ALLOW_STATIC_BINDINGS=1 + "${LLDB_SOURCE_DIR}" + ) + ;; Darwin) # Set up flags to pass to xcodebuild lldb_xcodebuild_options=( @@ -1876,7 +1907,7 @@ tests_busted () for deployment_target in "${STDLIB_DEPLOYMENT_TARGETS[@]}"; do case ${deployment_target} in - linux-* | freebsd-* | macosx-*) + linux-* | freebsd-* | macosx-* | cygwin-*) # OK, we can run tests directly. ;; iphoneos-* | iphonesimulator-* | appletvos-* | appletvsimulator-* | watchos-* | watchsimulator-*) @@ -2103,6 +2134,8 @@ for deployment_target in "${HOST_TARGET}" "${CROSS_TOOLS_DEPLOYMENT_TARGETS[@]}" ;; FreeBSD) ;; + CYGWIN_NT-10.0) + ;; Darwin) set_lldb_build_mode pushd ${LLDB_SOURCE_DIR} @@ -2146,6 +2179,9 @@ for deployment_target in "${HOST_TARGET}" "${CROSS_TOOLS_DEPLOYMENT_TARGETS[@]}" LIB_TARGET="freebsd" ARCH_FLAG="--arch=\"${SWIFT_HOST_VARIANT_ARCH}\"" fi + if [[ $(uname -s) == "CYGWIN_NT-10.0" ]]; then + LIB_TARGET="windows" + fi if [[ $(uname -s) == "Darwin" ]]; then LIB_TARGET="macosx" ARCH_FLAG="" diff --git a/utils/swift_build_support/swift_build_support/targets.py b/utils/swift_build_support/swift_build_support/targets.py index 4643531376b36..825ee8e03f77b 100644 --- a/utils/swift_build_support/swift_build_support/targets.py +++ b/utils/swift_build_support/swift_build_support/targets.py @@ -44,6 +44,10 @@ def host_target(): if machine == 'amd64': return 'freebsd-x86_64' + elif system == 'CYGWIN_NT-10.0': + if machine == 'x86_64': + return 'cygwin-x86_64' + return None