diff --git a/CMakeLists.txt b/CMakeLists.txt index 932d5e6d8b1b5..18cf581a64f03 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -147,14 +147,20 @@ set(SWIFT_COMPILER_VERSION "" CACHE STRING set(CLANG_COMPILER_VERSION "" CACHE STRING "The internal version of the Clang compiler") -# Indicate whether Swift should attempt to use the lld linker. -set(SWIFT_ENABLE_LLD_LINKER TRUE CACHE BOOL - "Enable using the lld linker when available") - -# Indicate whether Swift should attempt to use the gold linker. -# This is not used on Darwin. -set(SWIFT_ENABLE_GOLD_LINKER TRUE CACHE BOOL - "Enable using the gold linker when available") +# Which default linker to use. Prefer LLVM_USE_LINKER if it set, otherwise use +# our own defaults. This should only be possible in a unified (not stand alone) +# build environment. +if(LLVM_USE_LINKER) + set(SWIFT_USE_LINKER_default "${LLVM_USE_LINKER}") +elseif(CMAKE_SYSTEM_NAME STREQUAL Windows AND NOT CMAKE_HOST_SYSTEM_NAME STREQUAL Windows) + set(SWIFT_USE_LINKER_default "lld") +elseif(CMAKE_SYSTEM_NAME STREQUAL Darwin) + set(SWIFT_USE_LINKER_default "") +else() + set(SWIFT_USE_LINKER_default "gold") +endif() +set(SWIFT_USE_LINKER ${SWIFT_USE_LINKER_default} CACHE STRING + "Build Swift with a non-default linker") set(SWIFT_TOOLS_ENABLE_LTO OFF CACHE STRING "Build Swift tools with LTO. One must specify the form of LTO by setting this to one of: 'full', 'thin'. This @@ -407,6 +413,8 @@ endif() if(MSVC OR "${CMAKE_SIMULATE_ID}" STREQUAL MSVC) include(ClangClCompileRules) +elseif(UNIX) + include(UnixCompileRules) endif() if(CMAKE_C_COMPILER_ID MATCHES Clang) @@ -426,19 +434,6 @@ if(SWIFT_BUILD_SYNTAXPARSERLIB OR SWIFT_BUILD_SOURCEKIT) endif() endif() -# -# Assume a new enough ar to generate the index at construction time. This avoids -# having to invoke ranlib as a secondary command. -# - -set(CMAKE_C_ARCHIVE_CREATE " crs ") -set(CMAKE_C_ARCHIVE_APPEND " qs ") -set(CMAKE_C_ARCHIVE_FINISH "") - -set(CMAKE_CXX_ARCHIVE_CREATE " crs ") -set(CMAKE_CXX_ARCHIVE_APPEND " qs ") -set(CMAKE_CXX_ARCHIVE_FINISH "") - # # Include CMake modules # @@ -560,9 +555,6 @@ if(XCODE) swift_common_xcode_cxx_config() endif() -include(SwiftCheckCXXNativeRegex) -check_cxx_native_regex(SWIFT_HAVE_WORKING_STD_REGEX) - # If SWIFT_HOST_VARIANT_SDK not given, try to detect from the CMAKE_SYSTEM_NAME. if(SWIFT_HOST_VARIANT_SDK) set(SWIFT_HOST_VARIANT_SDK_default "${SWIFT_HOST_VARIANT_SDK}") diff --git a/README.md b/README.md index d8bfb65a54a9d..c219cecac3ab6 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ | **Ubuntu 16.04** | x86_64 | [![Build Status](https://ci.swift.org/job/oss-swift-incremental-RA-linux-ubuntu-16_04/lastCompletedBuild/badge/icon)](https://ci.swift.org/job/oss-swift-incremental-RA-linux-ubuntu-16_04)|[![Build Status](https://ci.swift.org/job/oss-swift-package-linux-ubuntu-16_04/lastCompletedBuild/badge/icon)](https://ci.swift.org/job/oss-swift-package-linux-ubuntu-16_04)| | **Ubuntu 18.04** | x86_64 | [![Build Status](https://ci.swift.org/job/oss-swift-incremental-RA-linux-ubuntu-18_04/lastCompletedBuild/badge/icon)](https://ci.swift.org/job/oss-swift-incremental-RA-linux-ubuntu-18_04)|[![Build Status](https://ci.swift.org/job/oss-swift-package-linux-ubuntu-18_04/lastCompletedBuild/badge/icon)](https://ci.swift.org/job/oss-swift-package-linux-ubuntu-18_04)| | **Ubuntu 20.04** | x86_64 | [![Build Status](https://ci.swift.org/job/oss-swift-package-ubuntu-20_04/lastCompletedBuild/badge/icon)](https://ci.swift.org/job/oss-swift-package-ubuntu-20_04)|[![Build Status](https://ci.swift.org/job/oss-swift-package-ubuntu-20_04/lastCompletedBuild/badge/icon)](https://ci.swift.org/job/oss-swift-package-ubuntu-20_04)| -| **CentOS 8** | x86_64 | [![Build Status](https://ci.swift.org/job/oss-swift-package-centos-8/lastCompletedBuild/badge/icon)](https://ci.swift.org/job/oss-swift-package-centos-8)|[![Build Status](https://ci.swift.org/job/oss-swift-package-linux-ubuntu-18_04/lastCompletedBuild/badge/icon)](https://ci.swift.org/job/oss-swift-package-centos-8)| +| **CentOS 8** | x86_64 | [![Build Status](https://ci.swift.org/job/oss-swift-package-centos-8/lastCompletedBuild/badge/icon)](https://ci.swift.org/job/oss-swift-package-centos-8)|[![Build Status](https://ci.swift.org/job/oss-swift-package-centos-8/lastCompletedBuild/badge/icon)](https://ci.swift.org/job/oss-swift-package-centos-8)| | **Amazon Linux 2** | x86_64 | [![Build Status](https://ci.swift.org/job/oss-swift-package-amazon-linux-2/lastCompletedBuild/badge/icon)](https://ci.swift.org/job/oss-swift-package-amazon-linux-2)|[![Build Status](https://ci.swift.org/job/oss-swift-package-amazon-linux-2/lastCompletedBuild/badge/icon)](https://ci.swift.org/job/oss-swift-package-amazon-linux-2)| **Swift Community-Hosted CI Platforms** @@ -85,6 +85,9 @@ Once you are able to build things successfully and have a compile-test-debug loop going, check out the [development tips](docs/DevelopmentTips.md) for better productivity while working on the compiler. +You can also skim [docs/README.md](/docs/README.md) to understand what +high-level documentation is available. + ### System Requirements macOS, Ubuntu Linux LTS, and the latest Ubuntu Linux release are currently @@ -151,8 +154,6 @@ with version 2 shipped with Ubuntu. **Note:** For Ubuntu 20.04, use `libpython2-dev` in place of the libpython-dev package above. -Build instructions for Ubuntu 14.04 LTS can be found [here](docs/Ubuntu14.md). - ### Getting Sources for Swift and Related Projects First create a directory for all of the Swift sources: diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index d6d417d6e7922..ef28ed87b2483 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -108,6 +108,7 @@ set(SWIFT_BENCH_MODULES single-source/LuhnAlgoLazy single-source/MapReduce single-source/Memset + single-source/Mirror single-source/MonteCarloE single-source/MonteCarloPi single-source/NSDictionaryCastToSwift diff --git a/benchmark/single-source/Mirror.swift b/benchmark/single-source/Mirror.swift new file mode 100644 index 0000000000000..94e9de21153ae --- /dev/null +++ b/benchmark/single-source/Mirror.swift @@ -0,0 +1,105 @@ +//===--- Mirror.swift ------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +// This test measures performance of Mirror and related things. +import TestsUtils + +public let TypeName = BenchmarkInfo( + name: "TypeName", + runFunction: run_TypeName, + tags: [.api, .String]) + +public let MirrorDefault = BenchmarkInfo( + name: "MirrorDefault", + runFunction: run_MirrorDefault, + tags: [.api, .String]) + +struct S1 { var s: String; var d: Double } +struct S2 { var i: Int; var a: [Range] } + +class C { var i: Int = 0 } +class D: C { var s: String = "" } + +enum E { + case a,b(Int) +} + +struct G { var t: T } +class H: C { var t: T; init(_ t: T) { self.t = t }} + +public func run_MirrorDefault(scale: Int) { + let N = 100*scale + + let s1 = S1(s: "foo", d: 3.14) + let s2 = S2(i: 42, a: [0..<4]) + let c = C() + let d = D() + let e = E.a + let f = E.b(99) + let g = G(t: 12.3) + let h = H<[Int]>([1,2,3]) + + var str = "" + + for _ in 0..(t: 12.3),Mirror.H>") +} + +func typename(of: T.Type) -> String { + "\(T.self)" +} + +public func run_TypeName(scale: Int) { + let N = 1_000*scale + var a: [String] = [] + a.reserveCapacity(16) + + for _ in 0...self)) + a.append(typename(of: G.self)) + a.append(typename(of: G.self)) + a.append(typename(of: H.self)) + a.append(typename(of: [S1].self)) + a.append(typename(of: [G].self)) + a.append(typename(of: [H].self)) + a.append(typename(of: S1?.self)) + a.append(typename(of: C?.self)) + blackHole(a) + } + + let expected = ["S1", + "S2", + "C", + "D", + "G", + "G", + "G", + "H", + "Array", + "Array>", + "Array>", + "Optional", + "Optional", + ] + CheckResults(a == expected) +} diff --git a/benchmark/utils/main.swift b/benchmark/utils/main.swift index b999acb8b41ac..cbf8aaedaa25c 100644 --- a/benchmark/utils/main.swift +++ b/benchmark/utils/main.swift @@ -96,6 +96,7 @@ import LuhnAlgoEager import LuhnAlgoLazy import MapReduce import Memset +import Mirror import MonteCarloE import MonteCarloPi import NibbleSort @@ -281,6 +282,7 @@ registerBenchmark(LuhnAlgoEager) registerBenchmark(LuhnAlgoLazy) registerBenchmark(MapReduce) registerBenchmark(Memset) +registerBenchmark(MirrorDefault) registerBenchmark(MonteCarloE) registerBenchmark(MonteCarloPi) registerBenchmark(NSDictionaryCastToSwift) @@ -366,6 +368,7 @@ registerBenchmark(Suffix) registerBenchmark(SuperChars) registerBenchmark(TwoSum) registerBenchmark(TypeFlood) +registerBenchmark(TypeName) registerBenchmark(UTF8Decode) registerBenchmark(Walsh) registerBenchmark(WordCount) diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake index 09abb13345bb4..cbef2b8534d4f 100644 --- a/cmake/modules/AddSwift.cmake +++ b/cmake/modules/AddSwift.cmake @@ -75,25 +75,10 @@ function(_set_target_prefix_and_suffix target kind sdk) endif() endfunction() -function(is_darwin_based_sdk sdk_name out_var) - if ("${sdk_name}" STREQUAL "OSX" OR - "${sdk_name}" STREQUAL "IOS" OR - "${sdk_name}" STREQUAL "IOS_SIMULATOR" OR - "${sdk_name}" STREQUAL "TVOS" OR - "${sdk_name}" STREQUAL "TVOS_SIMULATOR" OR - "${sdk_name}" STREQUAL "WATCHOS" OR - "${sdk_name}" STREQUAL "WATCHOS_SIMULATOR") - set(${out_var} TRUE PARENT_SCOPE) - else() - set(${out_var} FALSE PARENT_SCOPE) - endif() -endfunction() - # Usage: # _add_host_variant_c_compile_link_flags(name) function(_add_host_variant_c_compile_link_flags name) - is_darwin_based_sdk("${SWIFT_HOST_VARIANT_SDK}" IS_DARWIN) - if(IS_DARWIN) + if(SWIFT_HOST_VARIANT_SDK IN_LIST SWIFT_APPLE_PLATFORMS) set(DEPLOYMENT_VERSION "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_DEPLOYMENT_VERSION}") endif() @@ -107,7 +92,7 @@ function(_add_host_variant_c_compile_link_flags name) set(_sysroot "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_ARCH_${SWIFT_HOST_VARIANT_ARCH}_PATH}") - if(IS_DARWIN) + if(SWIFT_HOST_VARIANT_SDK IN_LIST SWIFT_APPLE_PLATFORMS) target_compile_options(${name} PRIVATE -isysroot;${_sysroot}) elseif(NOT SWIFT_COMPILER_IS_MSVC_LIKE AND NOT "${_sysroot}" STREQUAL "/") target_compile_options(${name} PRIVATE --sysroot=${_sysroot}) @@ -116,13 +101,13 @@ function(_add_host_variant_c_compile_link_flags name) if(SWIFT_HOST_VARIANT_SDK STREQUAL ANDROID) # lld can handle targeting the android build. However, if lld is not # enabled, then fallback to the linker included in the android NDK. - if(NOT SWIFT_ENABLE_LLD_LINKER) + if(NOT SWIFT_USE_LINKER STREQUAL "lld") swift_android_tools_path(${SWIFT_HOST_VARIANT_ARCH} tools_path) target_compile_options(${name} PRIVATE -B${tools_path}) endif() endif() - if(IS_DARWIN) + if(SWIFT_HOST_VARIANT_SDK IN_LIST SWIFT_APPLE_PLATFORMS) # We collate -F with the framework path to avoid unwanted deduplication # of options by target_compile_options -- this way no undesired # side effects are introduced should a new search path be added. @@ -368,18 +353,9 @@ function(_add_host_variant_link_flags target) endif() if(NOT SWIFT_COMPILER_IS_MSVC_LIKE) - # FIXME: On Apple platforms, find_program needs to look for "ld64.lld" - find_program(LDLLD_PATH "ld.lld") - if((SWIFT_ENABLE_LLD_LINKER AND LDLLD_PATH AND NOT APPLE) OR - (SWIFT_HOST_VARIANT_SDK STREQUAL WINDOWS AND NOT CMAKE_SYSTEM_NAME STREQUAL WINDOWS)) - target_link_options(${target} PRIVATE -fuse-ld=lld) - elseif(SWIFT_ENABLE_GOLD_LINKER AND - "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_OBJECT_FORMAT}" STREQUAL "ELF") - if(CMAKE_HOST_SYSTEM_NAME STREQUAL Windows) - target_link_options(${target} PRIVATE -fuse-ld=gold.exe) - else() - target_link_options(${target} PRIVATE -fuse-ld=gold) - endif() + if(SWIFT_USE_LINKER) + target_link_options(${target} PRIVATE + -fuse-ld=${SWIFT_USE_LINKER}$<$:.exe>) endif() endif() @@ -475,20 +451,16 @@ function(add_swift_host_library name) LIBRARY_DIR ${SWIFT_LIBRARY_OUTPUT_INTDIR}) if(SWIFT_HOST_VARIANT_SDK IN_LIST SWIFT_APPLE_PLATFORMS) - set_target_properties(${name} - PROPERTIES + set_target_properties(${name} PROPERTIES INSTALL_NAME_DIR "@rpath") elseif(SWIFT_HOST_VARIANT_SDK STREQUAL LINUX) - set_target_properties(${name} - PROPERTIES + set_target_properties(${name} PROPERTIES INSTALL_RPATH "$ORIGIN:/usr/lib/swift/linux") elseif(SWIFT_HOST_VARIANT_SDK STREQUAL CYGWIN) - set_target_properties(${name} - PROPERTIES + set_target_properties(${name} PROPERTIES INSTALL_RPATH "$ORIGIN:/usr/lib/swift/cygwin") elseif(SWIFT_HOST_VARIANT_SDK STREQUAL "ANDROID") - set_target_properties(${name} - PROPERTIES + set_target_properties(${name} PROPERTIES INSTALL_RPATH "$ORIGIN") endif() @@ -526,7 +498,6 @@ function(add_swift_host_library name) endif() set_target_properties(${name} PROPERTIES - CXX_STANDARD 14 NO_SONAME YES) endif() @@ -556,14 +527,10 @@ function(add_swift_host_library name) "LINKER:-current_version,${SWIFT_COMPILER_VERSION}") endif() - set(DEPLOYMENT_VERSION "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_DEPLOYMENT_VERSION}") - # MSVC, clang-cl, gcc don't understand -target. - if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT SWIFT_COMPILER_IS_MSVC_LIKE) - get_target_triple(target target_variant "${SWIFT_HOST_VARIANT_SDK}" "${SWIFT_HOST_VARIANT_ARCH}" - MACCATALYST_BUILD_FLAVOR "" - DEPLOYMENT_VERSION "${DEPLOYMENT_VERSION}") - target_link_options(${name} PRIVATE -target;${target}) - endif() + get_target_triple(target target_variant "${SWIFT_HOST_VARIANT_SDK}" "${SWIFT_HOST_VARIANT_ARCH}" + MACCATALYST_BUILD_FLAVOR "" + DEPLOYMENT_VERSION "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_DEPLOYMENT_VERSION}") + target_link_options(${name} PRIVATE -target;${target}) endif() add_dependencies(dev ${name}) diff --git a/cmake/modules/AddSwiftUnittests.cmake b/cmake/modules/AddSwiftUnittests.cmake index e088997741eb1..811b455bd3ed2 100644 --- a/cmake/modules/AddSwiftUnittests.cmake +++ b/cmake/modules/AddSwiftUnittests.cmake @@ -57,15 +57,9 @@ function(add_swift_unittest test_dirname) _ENABLE_EXTENDED_ALIGNED_STORAGE) endif() - find_program(LDLLD_PATH "ld.lld") - # Strangely, macOS finds lld and then can't find it when using -fuse-ld= - if(SWIFT_ENABLE_LLD_LINKER AND LDLLD_PATH AND NOT APPLE) + if(SWIFT_USE_LINKER) set_property(TARGET "${test_dirname}" APPEND_STRING PROPERTY - LINK_FLAGS " -fuse-ld=lld") - elseif(SWIFT_ENABLE_GOLD_LINKER AND - "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_OBJECT_FORMAT}" STREQUAL "ELF") - set_property(TARGET "${test_dirname}" APPEND_STRING PROPERTY - LINK_FLAGS " -fuse-ld=gold") + LINK_FLAGS " -fuse-ld=${SWIFT_USE_LINKER}") endif() if(SWIFT_ANALYZE_CODE_COVERAGE) diff --git a/cmake/modules/SwiftCheckCXXNativeRegex.cmake b/cmake/modules/SwiftCheckCXXNativeRegex.cmake deleted file mode 100644 index 2e320bd8f9fb9..0000000000000 --- a/cmake/modules/SwiftCheckCXXNativeRegex.cmake +++ /dev/null @@ -1,32 +0,0 @@ -function(check_cxx_native_regex result_var_name) - if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") - # Apple operating systems use libc++, which has a working std::regex. - set("${result_var_name}" TRUE PARENT_SCOPE) - else() - if(CMAKE_CROSSCOMPILING) - # Can't run C source when cross-compiling; assume false until we have a static check. - set("${result_var_name}" FALSE PARENT_SCOPE) - else() - # libstdc++ 4.8 has an incomplete std::regex implementation, and crashes - # on many regexes. - # libstdc++ 4.9 works. - set(std_regex_test_source - " - #include - const std::regex broken_regex{ - \"([a]+)\", - std::regex::ECMAScript | std::regex::nosubs}; - - int main() {} - ") - - check_cxx_source_runs("${std_regex_test_source}" "${result_var_name}_TEST") - if ("${${result_var_name}_TEST}") - set("${result_var_name}" TRUE PARENT_SCOPE) - else() - set("${result_var_name}" FALSE PARENT_SCOPE) - endif() - endif() - endif() -endfunction() - diff --git a/cmake/modules/SwiftConfigureSDK.cmake b/cmake/modules/SwiftConfigureSDK.cmake index 51aceb3d2a797..09d45cc3a34a3 100644 --- a/cmake/modules/SwiftConfigureSDK.cmake +++ b/cmake/modules/SwiftConfigureSDK.cmake @@ -374,7 +374,7 @@ macro(configure_sdk_unix name architectures) # If the module triple wasn't set explicitly, it's the same as the triple. if(NOT SWIFT_SDK_${prefix}_ARCH_${arch}_MODULE) - set(SWIFT_SDK_${prefix}_ARCH_${arch}_MODULE "${SWIFT_SDK_${prefix}_ARCH_${arch}_MODULE}") + set(SWIFT_SDK_${prefix}_ARCH_${arch}_MODULE "${SWIFT_SDK_${prefix}_ARCH_${arch}_TRIPLE}") endif() endforeach() @@ -407,7 +407,7 @@ macro(configure_sdk_windows name environment architectures) "${arch}-unknown-windows-${environment}") endif() - set(SWIFT_SDK_${prefix}_ARCH_${arch}_MODULE "${SWIFT_SDK_${prefix}_ARCH_${arch}_MODULE}") + set(SWIFT_SDK_${prefix}_ARCH_${arch}_MODULE "${SWIFT_SDK_${prefix}_ARCH_${arch}_TRIPLE}") # NOTE: set the path to / to avoid a spurious `--sysroot` from being passed # to the driver -- rely on the `INCLUDE` AND `LIB` environment variables diff --git a/cmake/modules/UnixCompileRules.cmake b/cmake/modules/UnixCompileRules.cmake new file mode 100644 index 0000000000000..1f1bd57ce10db --- /dev/null +++ b/cmake/modules/UnixCompileRules.cmake @@ -0,0 +1,13 @@ + +# +# Assume a new enough ar to generate the index at construction time. This avoids +# having to invoke ranlib as a secondary command. +# + +set(CMAKE_C_ARCHIVE_CREATE " crs ") +set(CMAKE_C_ARCHIVE_APPEND " qs ") +set(CMAKE_C_ARCHIVE_FINISH "") + +set(CMAKE_CXX_ARCHIVE_CREATE " crs ") +set(CMAKE_CXX_ARCHIVE_APPEND " qs ") +set(CMAKE_CXX_ARCHIVE_FINISH "") diff --git a/docs/ABI/Mangling.rst b/docs/ABI/Mangling.rst index c301dbf6fbe26..d21ca5334d30a 100644 --- a/docs/ABI/Mangling.rst +++ b/docs/ABI/Mangling.rst @@ -589,7 +589,7 @@ mangled in to disambiguate. impl-function-type ::= type* 'I' FUNC-ATTRIBUTES '_' impl-function-type ::= type* generic-signature 'I' FUNC-ATTRIBUTES '_' - FUNC-ATTRIBUTES ::= PATTERN-SUBS? INVOCATION-SUBS? PSEUDO-GENERIC? CALLEE-ESCAPE? DIFFERENTIABILITY-KIND? CALLEE-CONVENTION FUNC-REPRESENTATION? COROUTINE-KIND? (PARAM-CONVENTION PARAM-DIFFERENTIABILITY?)* RESULT-CONVENTION* ('Y' PARAM-CONVENTION)* ('z' RESULT-CONVENTION)? + FUNC-ATTRIBUTES ::= PATTERN-SUBS? INVOCATION-SUBS? PSEUDO-GENERIC? CALLEE-ESCAPE? DIFFERENTIABILITY-KIND? CALLEE-CONVENTION FUNC-REPRESENTATION? COROUTINE-KIND? (PARAM-CONVENTION PARAM-DIFFERENTIABILITY?)* RESULT-CONVENTION* ('Y' PARAM-CONVENTION)* ('z' RESULT-CONVENTION RESULT-DIFFERENTIABILITY?)? PATTERN-SUBS ::= 's' // has pattern substitutions INVOCATION-SUB ::= 'I' // has invocation substitutions @@ -634,6 +634,8 @@ mangled in to disambiguate. RESULT-CONVENTION ::= 'u' // unowned inner pointer RESULT-CONVENTION ::= 'a' // auto-released + RESULT-DIFFERENTIABILITY ::= 'w' // @noDerivative + For the most part, manglings follow the structure of formal language types. However, in some cases it is more useful to encode the exact implementation details of a function type. diff --git a/docs/Branches.md b/docs/Branches.md index e533c3af5e351..083f89610419d 100644 --- a/docs/Branches.md +++ b/docs/Branches.md @@ -58,15 +58,22 @@ You can use any of the branch names as the argument to `--scheme`, such as `mast - LLVM Project: the destination branch depends on the kind of change that must be made: - 1) LLVM Project changes that don't depend on Swift: New commits go to `master` in the upstream [llvm-project](https://github.com/llvm/llvm-project). + 1) LLVM Project changes that don't depend on Swift + + - New commits go to `master` in the upstream [llvm-project](https://github.com/llvm/llvm-project). - ... then these commits can be cherry-picked to an appropriate, `swift/master` aligned `apple/stable/*` branch in Apple's fork of [llvm-project](https://github.com/apple/llvm-project). Please see - [Apple's branching scheme](https://github.com/apple/llvm-project/blob/apple/master/apple-docs/AppleBranchingScheme.md) - document to determine which `apple/stable/*` branch you should cherry-pick to. + - Then cherry-pick these commits to an appropriate, `swift/master` aligned `apple/stable/*` branch in Apple's fork of [llvm-project](https://github.com/apple/llvm-project). Please see [Apple's branching scheme](https://github.com/apple/llvm-project/blob/apple/master/apple-docs/AppleBranchingScheme.md) document to determine which `apple/stable/*` branch you should cherry-pick to. + + Note that **no new changes should be submitted directly to `apple/master`**. We are actively working on eliminating the differences from upstream LLVM. - 2) Changes that depend on Swift (this only applies to LLDB): new commits go to `swift/master-next` + 2) Changes that depend on Swift (this only applies to LLDB) + - New commits go to `swift/master` (_not_ an `apple/stable/*` branch, as these shouldn't contain changes that depend on Swift). - ...then cherry-pick to the release branch (`swift/swift-x.y-branch`) if necessary, following the appropriate release process. (Usually this means filling out a standard template, finding someone to review your code if that hasn't already happened, and getting approval from that repo's *release manager.)* + - Then cherry-pick these commits to `swift/master-next`. + + - If necessary, cherry-pick to the release branch (`swift/release/x.y`), following the appropriate release process. (Usually this means filling out a standard template, finding someone to review your code if that hasn't already happened, and getting approval from that repo's *release manager.)* + + In the long term we want to eliminate the differences from upstream LLVM for these changes as well, but for now there is no concrete plan. So, submitting to `swift/master-next` continues to be allowed. ## Automerging diff --git a/docs/DebuggingTheCompiler.md b/docs/DebuggingTheCompiler.md index 51c6fe0440c90..061ed609780a3 100644 --- a/docs/DebuggingTheCompiler.md +++ b/docs/DebuggingTheCompiler.md @@ -64,19 +64,19 @@ Here is how to dump the IR after the main phases of the Swift compiler * **Parser** To print the AST after parsing: -```bash +```sh swiftc -dump-ast -O file.swift ``` * **SILGen** To print the SIL immediately after SILGen: -```bash +```sh swiftc -emit-silgen -O file.swift ``` * **Mandatory SIL passes** To print the SIL after the mandatory passes: -```bash +```sh swiftc -emit-sil -Onone file.swift ``` @@ -87,25 +87,25 @@ swiftc -emit-sil -Onone file.swift * **Performance SIL passes** To print the SIL after the complete SIL optimization pipeline: -```bash +```sh swiftc -emit-sil -O file.swift ``` * **IRGen** To print the LLVM IR after IR generation: -```bash +```sh swiftc -emit-ir -Xfrontend -disable-llvm-optzns -O file.swift ``` * **LLVM passes** To print the LLVM IR after LLVM passes: -```bash +```sh swiftc -emit-ir -O file.swift ``` * **Code generation** To print the final generated code: -```bash +```sh swiftc -S -O file.swift ``` diff --git a/docs/DifferentiableProgramming.md b/docs/DifferentiableProgramming.md index c40dd3da310ff..0cec90aa47712 100644 --- a/docs/DifferentiableProgramming.md +++ b/docs/DifferentiableProgramming.md @@ -1079,11 +1079,6 @@ public extension Differentiable where Self == TangentVector { mutating func move(along direction: TangentVector) { self += direction } - - @noDerivative - var zeroTangentVectorInitializer: () -> TangentVector { - { .zero } - } } ``` @@ -1144,8 +1139,8 @@ extension Array: Differentiable where Element: Differentiable { @noDerivative public var zeroTangentVectorInitializer: () -> TangentVector { - { [count = self.count] in - TangentVector(Array(repeating: .zero, count: count)) + { [zeroInits = map(\.zeroTangentVectorInitializer)] in + TangentVector(zeroInits.map { $0() }) } } } @@ -1238,8 +1233,15 @@ the same effective access level as their corresponding original properties. A `move(along:)` method is synthesized with a body that calls `move(along:)` for each pair of the original property and its corresponding property in -`TangentVector`. Similarly, `zeroTangentVector` is synthesized to return a -tangent vector that consists of each stored property's `zeroTangentVector`. +`TangentVector`. + +Similarly, when memberwise derivation is possible, +`zeroTangentVectorInitializer` is synthesized to return a closure that captures +and calls each stored property's `zeroTangentVectorInitializer` closure. +When memberwise derivation is not possible (e.g. for custom user-defined +`TangentVector` types), `zeroTangentVectorInitializer` is synthesized as a +`{ TangentVector.zero }` closure. + Here's an example: ```swift @@ -1251,14 +1253,17 @@ struct Foo: @memberwise Differentiable { @noDerivative let helperVariable: T // The compiler synthesizes: + // // struct TangentVector: Differentiable, AdditiveArithmetic { // var x: T.TangentVector // var y: U.TangentVector // } + // // mutating func move(along direction: TangentVector) { // x.move(along: direction.x) // y.move(along: direction.y) // } + // // @noDerivative // var zeroTangentVectorInitializer: () -> TangentVector { // { [xTanInit = x.zeroTangentVectorInitializer, @@ -1278,8 +1283,8 @@ properties are declared to conform to `AdditiveArithmetic`. There are no `@noDerivative` stored properties. In these cases, the compiler will make `TangentVector` be a type alias for Self. -Method `move(along:)` and property `zeroTangentVector` will not be synthesized -because a default implementation already exists. +Method `move(along:)` will not be synthesized because a default implementation +already exists. ```swift struct Point: @memberwise Differentiable, @memberwise AdditiveArithmetic { @@ -1287,7 +1292,16 @@ struct Point: @memberwise Differentiable, @memberwise AdditiveArithmeti var x, y: T // The compiler synthesizes: + // // typealias TangentVector = Self + // + // @noDerivative + // var zeroTangentVectorInitializer: () -> TangentVector { + // { [xTanInit = x.zeroTangentVectorInitializer, + // yTanInit = y.zeroTangentVectorInitializer] in + // TangentVector(x: xTanInit(), y: yTanInit()) + // } + // } } ``` diff --git a/docs/HowToGuides/RunningIncludeWhatYouUse.md b/docs/HowToGuides/RunningIncludeWhatYouUse.md new file mode 100644 index 0000000000000..1ffa7e2e7571f --- /dev/null +++ b/docs/HowToGuides/RunningIncludeWhatYouUse.md @@ -0,0 +1,286 @@ +# How to run include-what-you-use (IWYU) on the Swift project + +[include-what-you-use (IWYU)](https://include-what-you-use.org) is a +Clang-based tool that analyzes `#include`s in a file and makes suggestions to +add or remove `#include`s based on usage in the code. This has two key benefits: + +- Removing unused `#include` statements reduces work for the compiler. +- Adding `#include` statements for usage avoids a refactoring in a header + file from breaking downstream implementation files due to accidental + transitive usage. + +Running IWYU is a bit tricky, so this how-to guide provides the steps for how +to get it up and running on the Swift project for macOS. +If you get IWYU working on a different platform and some steps need to be +changed, please update this document with platform-specific steps. + +- [Pre-requisites](#pre-requisites) +- [Cloning and branch checkout](#cloning-and-branch-checkout) +- [Building IWYU](#building-iwyu) +- [Running IWYU](#running-iwyu) +- [Debugging](#debugging) + +## Pre-requisites + +- A built Swift project with exported compilation commands. + By default, compilation commands are generated in the file + `build/[BuildSystem]-[BuildVariant]/swift-[target]/compile_commands.json`. + Check that this file is present before proceeding. + - If this file is missing, try building with + `CMAKE_EXPORT_COMPILATION_COMMANDS=ON`. If you use `build-script` to + manage your builds, you can do this with + ``` + swift/utils/build-script \ + --extra-cmake-options='-DCMAKE_EXPORT_COMPILATION_COMMANDS=ON' + ``` +- Install [`jq`](https://stedolan.github.io/jq/). It's not strictly necessary, + but we will use it for some JSON munging. + +## Cloning and branch checkout + +The directory structure we will be using is + +``` +swift-project/ + |--- build/ + | |--- [BuildSystem]-[BuildVariant]/ + | | |--- swift-[target]/ + | | | |--- compile_commands.json + | | | `--- ... + | | |--- iwyu-[target]/ + | | `--- ... + | `--- ... + |--- swift/ + |--- iwyu/ + | |--- src/ + | |--- logs/ + | `--- scripts/ + `--- ... +``` + +As a running example, the description below uses `[BuildSystem] = Ninja`, +`[BuildVariant] = ReleaseAssert` and `[target] = macosx-x86_64`. + +Start with `swift-project` as the working directory. + +1. Check out IWYU. + ``` + mkdir -p iwyu/src + git clone https://github.com/include-what-you-use/include-what-you-use.git iwyu/src + ``` +2. Find out the version of the `clang` built recently. + ``` + build/Ninja-ReleaseAssert/llvm-macosx-x86_64/bin/clang --version + ``` + This should say something like `clang version 10.0.0` or similar. +3. Based on the `clang` version, make sure you check out the correct branch. + ``` + git -C iwyu/src checkout clang_10 + ``` + +## Building IWYU + +1. Configure IWYU with CMake. + ``` + cmake -G Ninja \ + -DCMAKE_PREFIX_PATH=build/Ninja-ReleaseAssert/llvm-macosx-x86_64 \ + -DCMAKE_CXX_STANDARD=14 \ + -B build/Ninja-ReleaseAssert/iwyu-macosx-x86_64 \ + iwyu/src + ``` +2. Build IWYU + ``` + cmake --build build/Ninja-ReleaseAssert/iwyu-macosx-x86_64 + ``` +3. Create an extra symlink so IWYU can find necessary Clang headers: + ``` + ln -sF build/Ninja-ReleaseAssert/llvm-macosx-x86_64/lib build/Ninja-ReleaseAssert/iwyu-macosx-x86_64/lib + ``` +4. Spot check IWYU for a basic C example. + ``` + echo '#include ' > tmp.c + ./bin/include-what-you-use tmp.c -E -o /dev/null \ + -I "$(xcrun --show-sdk-path)/usr/include" + rm tmp.c + ``` + You should see output like: + ``` + tmp.c should add these lines: + + tmp.c should remove these lines: + - #include // lines 1-1 + + The full include-list for tmp.c: + --- + ``` +5. Spot check IWYU for a basic C++ example. Notice the extra C++-specific + include path. + ``` + echo '#include \n#include ' > tmp.cpp + ./bin/include-what-you-use tmp.cpp -E -o /dev/null \ + -I "$(clang++ -print-resource-dir)/../../../include/c++/v1" \ + -I "$(xcrun --show-sdk-path)/usr/include" + rm tmp.cpp + ``` + You should see output like: + ``` + tmp.cpp should add these lines: + + tmp.cpp should remove these lines: + - #include // lines 2-2 + - #include // lines 1-1 + + The full include-list for tmp.cpp: + --- + ``` + +## Running IWYU + +1. Create a directory, say `iwyu/scripts`, and copy the following script there. + + ``` + #!/usr/bin/env bash + + # iwyu_run.sh + set -eu + + SWIFT_PROJECT_DIR="$HOME/swift-project" + SWIFT_BUILD_DIR="$SWIFT_PROJECT_DIR/build/Ninja-ReleaseAssert/swift-macosx-x86_64" + + pushd "$SWIFT_BUILD_DIR" + + if [ -f original_compile_commands.json ]; then + mv original_compile_commands.json compile_commands.json + fi + + # HACK: The additional include path needs to be added before other include + # paths, it doesn't seem to work if we add it at the end. + # It is ok to rely on the presence of `-D__STDC_LIMIT_MACROS` flag, since + # it is added by the LLVM CMake configuration for all compilation commands. + ( EXTRA_CXX_INCLUDE_DIR="$(clang++ -print-resource-dir)/../../../include/c++/v1"; + cat compile_commands.json \ + | jq '[.[] | select(.file | test("\\.mm" | "\\.m") | not) | {directory: .directory, command: (.command + " -Wno-everything -ferror-limit=1"), file: .file}]' \ + | sed -e "s|-D__STDC_LIMIT_MACROS |-D__STDC_LIMIT_MACROS -I $EXTRA_CXX_INCLUDE_DIR |" \ + ) > filtered_compile_commands.json + + mv compile_commands.json original_compile_commands.json + mv filtered_compile_commands.json compile_commands.json + + mkdir -p "$SWIFT_PROJECT_DIR/iwyu/logs" + + ( PATH="$SWIFT_PROJECT_DIR/iwyu/build/bin:$PATH"; \ + "$SWIFT_PROJECT_DIR/iwyu/include-what-you-use/iwyu_tool.py" -p "$SWIFT_BUILD_DIR" + ) | tee "$SWIFT_PROJECT_DIR/iwyu/logs/suggestions.log" + + popd + + ``` + + We filter out Objective-C files because IWYU does not support Objective-C. + If that step is missed, you might hit errors like: + ``` + iwyu.cc:2097: Assertion failed: TODO(csilvers): for objc and clang lang extensions + ``` + +2. Update the `SWIFT_PROJECT_DIR` and `SWIFT_BUILD_DIR` variables based on + your project and build directories. + +3. Run the script. + ``` + chmod +x iwyu/scripts/iwyu_run.sh + iwyu/scripts/iwyu_run.sh + ``` + This will generate a log file under `iwyu/logs/suggestions.log`. + Note that IWYU might take several hours to run, depending on your system. + +NOTE: The IWYU README suggests several different ways of running IWYU on a +CMake project, including using the `CMAKE_CXX_INCLUDE_WHAT_YOU_USE` and +`CMAKE_C_INCLUDE_WHAT_YOU_USE` variables. At the time of writing, those did +not reliably work on macOS; suggestions were generated only for specific +subprojects (e.g. the stdlib) and not others (e.g. the compiler). +Using CMake variables also requires reconfiguring and rebuilding, which makes +debugging much more time-consuming. + +## Debugging + +While the above steps should work, in case you run into issues, you might find +the following steps for debugging helpful. + +### Try different include path ordering + +If you see errors with ``, or similar system headers, one thing that might +be happening is that the include paths are in the wrong order. Try moving the +include paths for the corresponding header before/after all other include paths. + +### Iterate on files one at a time + +Instead of trying to make changes to the CMake configuration and recompiling +the whole project, first try working on individual compilation commands as +emitted in `compile_commands.json` and see if IWYU works as expected. + +For each command, try replacing the compiler with the `include-what-you-use` +binary or `iwyu_stub.py` (below) to see if the behavior is as expected. +You may need to manually add some include paths as in `iwyu_run.sh` above. +Make sure you update paths in the script before it works. + +``` +#!/usr/bin/env python3 + +# iwyu_stub.py + +import os +import re +import subprocess +import sys + +clang_path = "/usr/bin/clang" +clangxx_path = "/usr/bin/clang++" +project_dir = "/Users/username/swift-project/" +iwyu_bin_path = project_dir + "iwyu/build/bin/include-what-you-use" +log_dir = project_dir + "iwyu/logs/" + +log_file = open(log_dir + "passthrough.log", "a+") + +argv = sys.argv + +def call_with_args(executable_path, args=argv): + new_argv = args[:] + new_argv[0] = executable_path + log_file.write("# about to run:\n{}\n#---\n".format(' '.join(new_argv))) + sys.exit(subprocess.call(new_argv)) + +# HACK: Relies on the compilation commands generated by CMake being +# of the form: +# +# /path/to/compiler -c MyFile.ext +# +def try_using_iwyu(argv): + return (argv[-2] == "-c") and ("/swift/" in argv[-1]) + +# Flag for quickly switching between IWYU and Clang for iteration. +# Useful for checking behavior for different include path combinations. +if argv[1] == "--forward-to-clangxx": + call_with_args(clangxx_path, args=([argv[0]] + argv[2:])) + +# Check that we are getting a compilation command. +if try_using_iwyu(argv): + _, ext = os.path.splitext(argv[-1]) + if ext == ".m": + call_with_args(clang_path) + elif ext == ".mm": + call_with_args(clangxx_path) + elif ext in [".cxx", ".cc", ".cpp", ".c"]: + call_with_args(iwyu_bin_path) + log_file.write( + "# Got a strange file extension.\n{}\n#---\n".format(' '.join(argv))) + call_with_args(iwyu_bin_path) +else: + # got something else, just forward to clang/clang++ + log_file.write( + "# Not going to try using iwyu.\n{}\n#---\n".format(' '.join(argv))) + _, ext = os.path.splitext(argv[-1]) + if ext == ".m" or ext == ".c": + call_with_args(clang_path) + else: + call_with_args(clangxx_path) +``` diff --git a/docs/Lexicon.md b/docs/Lexicon.md index 95b5bc175baf1..32e2d4acd8dfa 100644 --- a/docs/Lexicon.md +++ b/docs/Lexicon.md @@ -162,11 +162,36 @@ written "dupe". Pronounced the same way as the first syllable of A value whose type is a protocol composition (including a single protocol and *zero* protocols; the latter is the `Any` type). +## explicit module build + +A module build where all dependency modules (including Clang modules) are +passed to the compiler explicitly by an external build system, including +any modules in caches. See also: [implicit module build](#implicit-module-build) +and [fast dependency scanner](#fast-dependency-scanner). + +## fast dependency scanner + +A Swift compiler mode that scans a Swift module for import declarations and +resolves which modules will be loaded. It is based on the +[clang-scan-deps](https://llvm.org/devmtg/2019-04/slides/TechTalk-Lorenz-clang-scan-deps_Fast_dependency_scanning_for_explicit_modules.pdf) +library within Clang, for (Objective-)C modules, but is extended to also +understand textual Swift modules (.swiftinterface files). + +The fast dependency scanner outputs a graph of compilation steps which can be +used by a build system to schedule +[explicit module builds](#explicit-module-builds). + ## fragile Describes a type or function where making changes will break binary compatibility. See [LibraryEvolution.rst](LibraryEvolution.rst). +## gardening + +Describes contributions which fix code that is not executed +(such as in a manifesto or README) and written text +(correcting typos and grammatical errors). + ## generic environment Provides context for interpreting a type that may have generic parameters @@ -187,6 +212,17 @@ compared directly. ["if and only if"](https://en.wikipedia.org/wiki/If_and_only_if). This term comes from mathematics. +## implicit module build + +A module build where the compiler is free to transparently build dependent +modules (including Clang modules), and access modules in different caches as +necessary. For example, if a textual Swift module (.swiftinterface file) for +a dependency does not have a corresponding binary Swift module (.swiftmodulea +file), the compiler may transparently build a binary Swift module from the +textual one as a cache for future compiler jobs, without involving any external +build system that invoked the compiler. See also: +[explicit module build](#explicit-module-build). + ## interface type The type of a value or declaration outside its generic context. These types diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000000..dceb55fa82bda --- /dev/null +++ b/docs/README.md @@ -0,0 +1,323 @@ +# Documentation Index + +This page describes the overall organization of documentation for the Swift toolchain. +It is divided into the following sections: + +- [Tutorials](#tutorials) + gently guide you towards achieving introductory tasks, + while assuming minimal background knowledge. +- [How-To Guides](#how-to-guides) + help you complete specific tasks in a step-by-step fashion. +- [Explanations](#explanations) + discuss key subsystems and concepts, at a high level. + They also provide background information and talk about design tradeoffs. +- [Reference Guides](#reference-guides) + contain a thorough technical reference for complex topics. + They assume some overall understanding of surrounding subsystems. +- [Recommended Practices](#recommended-practices) + suggests guidelines for writing code and diagnostics. +- [Project Information](#project-information) + tracks continuous integration (CI), branching and release history. +- [Evolution Documents](#evolution-documents) + includes proposals and manifestos for changes to Swift. +- The [External Resources](#external-resources) section provides links to + valuable discussions about Swift development, in the form of talks + and blog posts. +- The [Uncategorized](#uncategorized) section is for documentation which does + not fit neatly into any of the above categories. We would like minimize + items in this section; avoid adding new documentation here. + +Sometimes documentation is not enough. +Especially if you are a new contributor, you might run into roadblocks +which are not addressed by the existing documentation. +Or they are addressed somewhere but you cannot find the relevant bits. +If you are stuck, please use the [development category][] on the Swift forums +to ask for help! + +Lastly, note that we are slowly moving towards a more structured form of +documentation, inspired by the Django project [[1][Django-docs-1]] +[[2][Django-docs-2]]. Hence parts of this page are aspirational +and do not reflect how much of the existing documentation is written. +Pull requests to clean up the [Uncategorized](#uncategorized) section, +or generally fill gaps in the documentation are very welcome. +If you would like to make major changes, such as adding entire new pieces of +documentation, please create a thread on the Swift forums under the +[development category][] to discuss your proposed changes. + +[development category]: https://forums.swift.org/c/development +[Django-docs-1]: https://docs.djangoproject.com/ +[Django-docs-2]: https://documentation.divio.com/#the-documentation-system + +## Tutorials + +- [libFuzzerIntegration.md](/docs/libFuzzerIntegration.md): + Using `libFuzzer` to fuzz Swift code. + +## How-To Guides + +- [DebuggingTheCompiler.md](/docs/DebuggingTheCompiler.md): + Describes a variety of techniques for debugging. +- Building for Android: + - [Android.md](/docs/Android.md): + How to run some simple programs and the Swift test suite on an Android device. + - [AndroidBuild.md](/docs/AndroidBuild.md): + How to build the Swift SDK for Android on Windows. +- Building for Windows: + - [Windows.md](/docs/Windows.md): + Overview on how to build Swift for Windows. + - [WindowsBuild.md](/docs/WindowsBuild.md): + How to build Swift on Windows using Visual Studio. + - [WindowsCrossCompile.md](/docs/WindowsCrossCompile.md): + How to cross compile Swift for Windows on a non-Windows host OS. +- [RunningIncludeWhatYouUse.md](/docs/RunningIncludeWhatYouUse.md): + Describes how to run [include-what-you-use](https://include-what-you-use.org) + on the Swift project. + +## Explanations + +- [ByteTree.md](/docs/ByteTree.md): + Describes the ByteTree binary format used for serializing syntax trees + in `libSyntax`. + +### Compiler and Runtime Subsystems + +- Driver: + - [Driver.md](/docs/Driver.md): + Provides an overview of the driver, compilation model, and the compiler's + command-line options. Useful for integration into build systems other than + SwiftPM or Xcode. + - [DriverInternals.md](/docs/DriverInternals.md): + Provides a bird's eye view of the driver's implementation. + +- [DependencyAnalysis.md](/docs/DependencyAnalysis.md): + Describes different kinds of dependencies across files in the same module, + important for understanding incremental builds. +- C and ObjC interoperability: Clang Importer and PrintAsObjC + - [CToSwiftNameTranslation.md](/docs/CToSwiftNameTranslation.md): + Describes how C and ObjC entities are imported into Swift + by the Clang Importer. + - [CToSwiftNameTranslation-OmitNeedlessWords.md](/docs/CToSwiftNameTranslation-OmitNeedlessWords.md): + Describes how the "Omit Needless Words" algorithm works, + making imported names more idiomatic. +- Type-checking and inference: + - [TypeChecker.rst](/docs/TypeChecker.rst): + Provides an overview of how type-checking and inference work. + - [RequestEvaluator.md](/docs/RequestEvaluator.md): + Describes the request evaluator architecture, which is used for + lazy type-checking and efficient caching. + - [Literal.md](/docs/Literal.md): + Describes type-checking and inference specifically for literals. +- [Serialization.rst](/docs/Serialization.rst): + Gives an overview of the LLVM bitcode format used for swiftmodules. + - [StableBitcode.md](/docs/StableBitcode.md): + Describes how to maintain compatibility when changing the serialization + format. +- SIL and SIL Optimizations: + - [SILProgrammersManual.md](/docs/SILProgrammersManual.md): + Provides an overview of the implementation of SIL in the compiler. + - [OptimizerDesign.md](/docs/OptimizerDesign.md): + Describes the design of the optimizer pipeline. + - [HighLevelSILOptimizations.rst](docs/HighLevelSILOptimizations.rst): + Describes how the optimizer understands the semantics of high-level + operations on currency data types and optimizes accordingly. + Includes a thorough discussion of the `@_semantics` attribute. + +### SourceKit subsystems + +- [SwiftLocalRefactoring.md](/docs/refactoring/SwiftLocalRefactoring.md): + Describes how refactorings work and how they can be tested. + +### Language subsystems + +- Swift's Object Model + - [LogicalObjects.md](): + Describes the differences between logical and physical objects and + introduces materialization and writeback. + - [MutationModel.rst]() +- [DocumentationComments.md](/docs/DocumentationComments.md): + Describes the format of Swift's documentation markup, including + specially-recognized sections. + +### Stdlib Design + +- [SequencesAndCollections.rst](/docs/SequencesAndCollections.rst): + Provides background on the design of different collection-related protocols. +- [StdlibRationales.rst](/docs/StdlibRationales.rst): + Provides rationale for common questions/complaints regarding design decisions + in the Swift stdlib. + +## Reference Guides + +- [DriverParseableOutput.md](/docs/DriverParseableOutput.md): + Describes the output format of the driver's `-parseable-output` flag, + which is suitable for consumption by editors and IDEs. +- [ObjCInterop.md](/docs/ObjCInterop.md) + Documents how Swift interoperates with ObjC code and the ObjC runtime. +- [LibraryEvolution.rst](/docs/LibraryEvolution.rst): + Specifies what changes can be made without breaking binary compatibility. +- [SIL.rst](/docs/SIL.rst): + Documents the Swift Intermediate Language (SIL). + - [TransparentAttr.md](/docs/TransparentAttr.md): + Documents the semantics of the `@_transparent` attribute. +- [Runtime.md](/docs/Runtime.md): + Describes the ABI interface to the Swift runtime. + +- [Lexicon.md](/docs/Lexicon.md): + Canonical reference for terminology used throughout the project. + +## Recommended Practices + +### Coding + +- [AccessControlInStdlib.rst](/docs/AccessControlInStdlib.rst): + Describes the policy for access control modifiers and related naming + conventions in the stdlib. + +- [IndexInvalidation.md](/docs/IndexInvalidation.md): + Describes the expected behavior of indexing APIs exposed by the stdlib. +- [StdlibAPIGuidelines.rst](/docs/StdlibAPIGuidelines.rst): + Provides guidelines for designing stdlib APIs. + +- [StandardLibraryProgrammersManual](/docs/StandardLibraryProgrammersManual.md): + Provides guidelines for working code in the stdlib. +- [OptimizationTips.rst](/docs/OptimizationTips.rst): + Provides guidelines for writing high-performance Swift code. + +### Diagnostics + +## Project Information + +- [Branches.md](/docs/Branches.md): + Describes how different branches are setup and what the automerger does. +- [ContinuousIntegration.md](ContinuousIntegration.md): + Describes the continuous integration setup, including the `@swift_ci` bot. + +## Evolution Documents + +### Manifestos + +- ABI Stability and Library Evolution + - [ABIStabilityManifesto.md](/docs/ABIStabilityManifesto.md): + Describes the goals and design for ABI stability. + - [LibraryEvolutionManifesto.md](/docs/LibraryEvolutionManifesto.md): + Describes the goals and design for Library Evolution. +- [BuildManifesto.md](BuildManifesto.md): + Provides an outline for modularizing the build system for the Swift toolchain. +- [CppInteroperabilityManifesto.md](CppInteroperabilityManifesto.md): + Describes the motivation and design for first-class Swift-C++ interoperability. +- [DifferentiableProgramming.md](/docs/DifferentiableProgramming.md): + Outlines a vision and design for first-class differentiable programming in Swift. +- [GenericsManifesto.md](/docs/GenericsManifesto.md): + Communicates a vision for making the generics system in Swift more powerful. +- [OwnershipManifesto.md](/docs/OwnershipManifesto.md): + Provides a framework for understanding ownership in Swift, + and highlights potential future directions for the language. +- [StringManifesto.md](/docs/StringManifesto.md): + Provides a long-term vision for the `String` type. + +### Proposals + +Old proposals are present in the [/docs/proposals](/docs/proposals) directory. +More recent proposals are located in the [apple/swift-evolution][] repository. +You can see the status of different proposals at +. + +[swift-evolution]: https://github.com/apple/swift-evolution + +### Surveys + +- [ErrorHandlingRationale.rst](/docs/ErrorHandlingRationale.rst): + Surveys error-handling in a variety of languages, and describes the rationale + behind the design of error handling in Swift. +- [weak.rst](/docs/weak.rst): + Discusses weak references, including the designs in different languages, + and proposes changes to Swift (pre-1.0). + + +### Archive + +These documents are known to be out-of-date and are superseded by other +documentation, primarily [The Swift Programming Language (TSPL)][]. +They are preserved mostly for historical interest. + +- [AccessControl.rst](/docs/AccessControl.swift) +- [Arrays.rst](/docs/Arrays.rst) + +- [Generics.rst](/docs/Generics.rst) +- [ErrorHandling.rst](/docs/ErrorHandling.rst) +- [StringDesign.rst](/docs/StringDesign.rst) +- [TextFormatting.rst](/docs/TextFormatting.rst) + +[The Swift Programming Language]: https://docs.swift.org/swift-book + +## External Resources + +The official [Swift blog](https://swift.org/blog/) contains a lot of useful +information, such as how library evolution works and how the compiler's new +diagnostic architecture is structured, helping us provide more precise +diagnostics. + +TODO: Add a new document ExternalResources.md. + +## Uncategorized + +### Needs refactoring + +The documents in this section might be worth breaking up into several documents, +and linking one document from the other. Breaking up into components will +provide greater clarity to contributors wanting to add new documentation. + +- [ARCOptimization.rst](/docs/ARCOptimization.rst): + Covers how ARC optimization works, with several examples. + TODO: Not clear if this is intended to be an explanation or a reference guide. +- [CompilerPerformance.md](/docs/CompilerPerformance.md): + Thoroughly discusses different ways of measuring compiler performance + and common pitfalls. + TODO: Consider breaking up into one high-level explanation explaining key + concepts and individual how-to guides that can be expanded independently. + Also, it's not the right place to explain details of different compiler modes. +- [DevelopmentTips.md](/docs/DevelopmentTips.md): + Contains an assortment of tips for better productivity when working on the + compiler. + TODO: Might be worthwhile to make a dedicated how-to guide or explanation. + It might also be valuable to introduce the tips in context, and have the + explanation link to all the different tips. +- [Diagnostics.md](/docs/Diagnostics.md): + Describes how to write diagnostic messages and associated educational notes. + TODO: Consider splitting into how-tos and recommended practices. + For example, we could have a how-to guide on adding a new diagnostic, + and have a recommended practices page which explains the writing style + for diagnostics and educational notes. +- [HowSwiftImportsCAPIs.md](/docs/HowSwiftImportsCAPIs.md): + Contains a thorough description of the mapping between C/ObjC entities and + Swift entities. + TODO: Not clear if this is intended to be language documentation + (for Swift developers), an explanation or a reference guide. +- [OptimizerCountersAnalysis.md](/docs/OptimizerCountersAnalysis.md): + TODO: Consider breaking up into a how-to guide + on dumping and analyzing the counters + and an explanation for the the counter collection system. +- [Testing.md](/docs/Testing.md): + TODO: Consider splitting into a how-to guide on writing a new test case + and an explanation for how the compiler is tested. +- [SwiftIndent.md](/docs/SwiftIndent.md): + TODO: Unclear if this is intended to be an explanation or a reference guide. +- [Random.md](/docs/Random.md): Stub. + +### Archive + +- [FailableInitializers.rst](/docs/FailableInitializers.rst): + Superseded by documentation in [The Swift Programming Language][]. +- [InitializerProblems.rst](/docs/InitializerProblems.rst): + Describes some complexities around initialization in Swift. + TODO: It would be great to have an explanation, say `InitializationModel.md`, + that covers the initialization model and new attributes like + `@_hasMissingDesignatedInitializers`. Some of this is covered in + [TSPL's initialization section][] but that doesn't include newly added + attributes. +- [Modules.rst](/docs/Module.rst): for Swift pre-1.0. +- [Swift3Compatibility.md](/docs/Swift3Compatibility.md): + Discusses the Swift 3 -> Swift 4 migration. +- [StoredAndComputedVariables.rst](): for Swift pre-1.0. + +[TSPL's initialization section]: https://docs.swift.org/swift-book/LanguageGuide/Initialization.html diff --git a/docs/Testing.md b/docs/Testing.md index 09306082790ed..b8f02d25b725b 100644 --- a/docs/Testing.md +++ b/docs/Testing.md @@ -38,7 +38,7 @@ uses an iOS 10.3 simulator configuration named "iPhone 5" for 32-bit testing. window, or with the command line: ```sh - xcrun simctl create 'iPhone 5' 'com.apple.CoreSimulator.SimDeviceType.iPhone-5' + xcrun simctl create 'iPhone 5' com.apple.CoreSimulator.SimDeviceType.iPhone-5 com.apple.CoreSimulator.SimRuntime.iOS-10-3 ``` 3. Append `--ios` to the `utils/build-script` command line (see below). diff --git a/docs/Ubuntu14.md b/docs/Ubuntu14.md deleted file mode 100644 index 78e2982e4ef53..0000000000000 --- a/docs/Ubuntu14.md +++ /dev/null @@ -1,24 +0,0 @@ -# Getting Started with Swift on Ubuntu 14.04 - -## Upgrade Clang -You'll need to upgrade your clang compiler for C++14 support and create a symlink. The minimum required version of clang may change, and may not be available on Ubuntu 14.04 in the future. -```bash -sudo apt-get install clang-3.9 -sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-3.9 100 -sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-3.9 100 -sudo update-alternatives --set clang /usr/bin/clang-3.9 -sudo update-alternatives --set clang++ /usr/bin/clang++-3.9 -``` - -## Upgrade CMake -You'll need to upgrade your CMake toolchain to a supported version by building a local copy. The minimum required version of CMake may change, and may not be available on Ubuntu 14.04 in the future. -```bash -wget https://cmake.org/files/v3.5/cmake-3.5.2.tar.gz -tar xf cmake-3.5.2.tar.gz -cd cmake-3.5.2 -./configure -make -sudo make install -sudo update-alternatives --install /usr/bin/cmake cmake /usr/local/bin/cmake 1 --force -cmake --version # This should print 3.5.2 -``` diff --git a/docs/WindowsBuild.md b/docs/WindowsBuild.md index 61c1e6ef2c5e2..28c4e28040420 100644 --- a/docs/WindowsBuild.md +++ b/docs/WindowsBuild.md @@ -1,27 +1,38 @@ # Building Swift on Windows -Visual Studio 2017 or newer is needed to build swift on Windows. +Visual Studio 2017 or newer is needed to build Swift on Windows. The free Community edition is sufficient to build Swift. -The following must take place in the **developer command prompt** (provided by Visual Studio). This shows up as "x64 Native Tools Command Prompt for VS2017" (or VS2019, VS2019 Preview depending on the Visual Studio that you are using) in the Start Menu. +The commands below (with the exception of installing Visual Studio) must be entered in the "**x64 Native** Tools Command Prompt for VS2017" (or VS2019, VS2019 Preview depending on the Visual Studio that you are using) in the Start Menu. This sets environment variables to select the correct target platform. ## Install dependencies -- Install the latest version of [Visual Studio](https://www.visualstudio.com/downloads/) -- Make sure to include "Programming Languages|Visual C++" and "Windows and Web Development|Universal Windows App Development|Windows SDK" in your installation. The following components are required: +### Visual Studio -1. Microsoft.VisualStudio.Component.Windows10SDK -2. Microsoft.VisualStudio.Component.Windows10SDK.17763 -3. Microsoft.VisualStudio.Component.VC.Tools.x86.x64 +An easy way to get most of the tools to build Swift is using the [Visual Studio installer](https://www.visualstudio.com/downloads/). This command installs all needed Visual Studio components as well as Python and Git: + +``` +vs_community ^ + --add Component.CPython2.x86 ^ + --add Component.CPython3.x64 ^ + --add Microsoft.VisualStudio.Component.Git ^ + --add Microsoft.VisualStudio.Component.VC.ATL ^ + --add Microsoft.VisualStudio.Component.VC.CMake.Project ^ + --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 ^ + --add Microsoft.VisualStudio.Component.Windows10SDK ^ + --add Microsoft.VisualStudio.Component.Windows10SDK.17763 +``` + +If you prefer you can install everything by hand, but make sure to include "Programming Languages|Visual C++" and "Windows and Web Development|Universal Windows App Development|Windows SDK" in your installation. The components listed above are required. The following [link](https://docs.microsoft.com/visualstudio/install/workload-component-id-vs-build-tools?view=vs-2019) helps in finding the component name given its ID for Visual Studio 2019. ### Python -In the Visual Studio installation program, under *Individual Components* +The command above already installs Python 2 and 3. Alternatively, in the Visual Studio installation program, under *Individual Components* 1. Install *Python 2*, either the 32-bit version (C:\Python27\\) or the 64-bit version (C:\Python27amd64\\) -> If you install the 64-bit version only, you will need to adjust `PYTHON_EXECUTABLE` below to `C:\Python27amd64\python.exe` + **Note:** If you install the 64-bit version only, you will need to adjust `PYTHON_EXECUTABLE` below to `C:\Python27amd64\python.exe` 2. Install *Python 3 64 bits (3.7.x)* @@ -139,6 +150,9 @@ cmake -B "S:\b\toolchain" ^ ninja -C S:\b\toolchain ``` +**Note:** If you installed only the 64-bit version of Python, you will need to adjust `PYTHON_EXECUTABLE` argument to `C:\Python27amd64\python.exe` + + ## Running Swift tests on Windows ```cmd diff --git a/include/swift/ABI/Metadata.h b/include/swift/ABI/Metadata.h index 4c8e9660a31f2..aa5ece97b10c2 100644 --- a/include/swift/ABI/Metadata.h +++ b/include/swift/ABI/Metadata.h @@ -1012,9 +1012,12 @@ struct TargetAnyClassMetadata : public TargetHeapMetadata { constexpr TargetAnyClassMetadata(TargetClassMetadata *superclass) : TargetHeapMetadata(MetadataKind::Class), - Superclass(superclass), - CacheData{nullptr, nullptr}, - Data(SWIFT_CLASS_IS_SWIFT_MASK) {} + Superclass(superclass) +#if SWIFT_OBJC_INTEROP + , CacheData{nullptr, nullptr}, + Data(SWIFT_CLASS_IS_SWIFT_MASK) +#endif + {} #if SWIFT_OBJC_INTEROP // Allow setting the metadata kind to a class ISA on class metadata. @@ -1022,13 +1025,12 @@ struct TargetAnyClassMetadata : public TargetHeapMetadata { using TargetMetadata::setClassISA; #endif - // Note that ObjC classes does not have a metadata header. + // Note that ObjC classes do not have a metadata header. /// The metadata for the superclass. This is null for the root class. ConstTargetMetadataPointer Superclass; - // TODO: remove the CacheData and Data fields in non-ObjC-interop builds. - +#if SWIFT_OBJC_INTEROP /// The cache data is used for certain dynamic lookups; it is owned /// by the runtime and generally needs to interoperate with /// Objective-C's use. @@ -1043,11 +1045,16 @@ struct TargetAnyClassMetadata : public TargetHeapMetadata { static constexpr StoredPointer offsetToData() { return offsetof(TargetAnyClassMetadata, Data); } +#endif /// Is this object a valid swift type metadata? That is, can it be /// safely downcast to ClassMetadata? bool isTypeMetadata() const { +#if SWIFT_OBJC_INTEROP return (Data & SWIFT_CLASS_IS_SWIFT_MASK); +#else + return true; +#endif } /// A different perspective on the same bit bool isPureObjC() const { @@ -1270,6 +1277,7 @@ struct TargetClassMetadata : public TargetAnyClassMetadata { return bounds; } +#if SWIFT_OBJC_INTEROP /// Given a statically-emitted metadata template, this sets the correct /// "is Swift" bit for the current runtime. Depending on the deployment /// target a binary was compiled for, statically emitted metadata templates @@ -1294,6 +1302,7 @@ struct TargetClassMetadata : public TargetAnyClassMetadata { assert(isTypeMetadata()); } +#endif bool isCanonicalStaticallySpecializedGenericMetadata() const { auto *description = getDescription(); @@ -2651,7 +2660,7 @@ struct TargetContextDescriptor { using ContextDescriptor = TargetContextDescriptor; -inline bool isCImportedModuleName(StringRef name) { +inline bool isCImportedModuleName(llvm::StringRef name) { // This does not include MANGLING_MODULE_CLANG_IMPORTER because that's // used only for synthesized declarations and not actual imported // declarations. @@ -2748,7 +2757,7 @@ class TargetGenericRequirementDescriptor { /// Retrieve the generic parameter that is the subject of this requirement, /// as a mangled type name. - StringRef getParam() const { + llvm::StringRef getParam() const { return swift::Demangle::makeSymbolicMangledNameStringRef(Param.get()); } @@ -2759,7 +2768,7 @@ class TargetGenericRequirementDescriptor { } /// Retrieve the right-hand type for a SameType or BaseClass requirement. - StringRef getMangledTypeName() const { + llvm::StringRef getMangledTypeName() const { assert(getKind() == GenericRequirementKind::SameType || getKind() == GenericRequirementKind::BaseClass); return swift::Demangle::makeSymbolicMangledNameStringRef(Type.get()); @@ -2990,7 +2999,7 @@ struct TargetExtensionContextDescriptor final using TrailingGenericContextObjects::getGenericContext; - StringRef getMangledExtendedContext() const { + llvm::StringRef getMangledExtendedContext() const { return Demangle::makeSymbolicMangledNameStringRef(ExtendedContext.get()); } @@ -3214,13 +3223,13 @@ struct TargetOpaqueTypeDescriptor final return (this ->template getTrailingObjects>())[i]; } - - StringRef getUnderlyingTypeArgument(unsigned i) const { + + llvm::StringRef getUnderlyingTypeArgument(unsigned i) const { assert(i < getNumUnderlyingTypeArguments()); const char *ptr = getUnderlyingTypeArgumentMangledName(i); return Demangle::makeSymbolicMangledNameStringRef(ptr); } - + static bool classof(const TargetContextDescriptor *cd) { return cd->getKind() == ContextDescriptorKind::OpaqueType; } diff --git a/include/swift/ABI/TypeIdentity.h b/include/swift/ABI/TypeIdentity.h index dadbd27abc73a..68a326f8c0c43 100644 --- a/include/swift/ABI/TypeIdentity.h +++ b/include/swift/ABI/TypeIdentity.h @@ -114,7 +114,7 @@ class TypeImportInfo { /// /// \return true if collection was successful. template - bool collect(StringRef value) { + bool collect(llvm::StringRef value) { #define check(CONDITION, COMMENT) \ do { \ if (!Asserting) { \ @@ -177,17 +177,17 @@ class TypeImportInfo { class ParsedTypeIdentity { public: /// The user-facing name of the type. - StringRef UserFacingName; + llvm::StringRef UserFacingName; /// The full identity of the type. /// Note that this may include interior '\0' characters. - StringRef FullIdentity; + llvm::StringRef FullIdentity; /// Any extended information that type might have. - llvm::Optional> ImportInfo; + llvm::Optional> ImportInfo; /// The ABI name of the type. - StringRef getABIName() const { + llvm::StringRef getABIName() const { if (ImportInfo && !ImportInfo->ABIName.empty()) return ImportInfo->ABIName; return UserFacingName; @@ -202,11 +202,11 @@ class ParsedTypeIdentity { return ImportInfo && !ImportInfo->RelatedEntityName.empty(); } - bool isRelatedEntity(StringRef entityName) const { + bool isRelatedEntity(llvm::StringRef entityName) const { return ImportInfo && ImportInfo->RelatedEntityName == entityName; } - StringRef getRelatedEntityName() const { + llvm::StringRef getRelatedEntityName() const { assert(isAnyRelatedEntity()); return ImportInfo->RelatedEntityName; } diff --git a/include/swift/AST/ASTContext.h b/include/swift/AST/ASTContext.h index 1e083e02c1ecc..4ff1060777427 100644 --- a/include/swift/AST/ASTContext.h +++ b/include/swift/AST/ASTContext.h @@ -407,6 +407,12 @@ class ASTContext final { array.size()); } + template + MutableArrayRef + AllocateCopy(const std::vector &vec, + AllocationArena arena = AllocationArena::Permanent) const { + return AllocateCopy(ArrayRef(vec), arena); + } template ArrayRef AllocateCopy(const SmallVectorImpl &vec, @@ -748,11 +754,13 @@ class ASTContext final { /// \param methods The list of @objc methods in this class that have this /// selector and are instance/class methods as requested. This list will be /// extended with any methods found in subsequent generations. - void loadObjCMethods(ClassDecl *classDecl, - ObjCSelector selector, - bool isInstanceMethod, - unsigned previousGeneration, - llvm::TinyPtrVector &methods); + /// + /// \param swiftOnly If true, only loads methods from imported Swift modules, + /// skipping the Clang importer. + void loadObjCMethods(ClassDecl *classDecl, ObjCSelector selector, + bool isInstanceMethod, unsigned previousGeneration, + llvm::TinyPtrVector &methods, + bool swiftOnly = false); /// Load derivative function configurations for the given /// AbstractFunctionDecl. diff --git a/include/swift/AST/ASTNode.h b/include/swift/AST/ASTNode.h index 892555418765d..4492c5063642a 100644 --- a/include/swift/AST/ASTNode.h +++ b/include/swift/AST/ASTNode.h @@ -30,7 +30,7 @@ namespace swift { class Stmt; class Decl; class Pattern; - class TypeLoc; + class TypeRepr; class DeclContext; class SourceLoc; class SourceRange; @@ -41,7 +41,7 @@ namespace swift { enum class StmtKind; struct ASTNode : public llvm::PointerUnion { + TypeRepr *> { // Inherit the constructors from PointerUnion. using PointerUnion::PointerUnion; diff --git a/include/swift/AST/ASTPrinter.h b/include/swift/AST/ASTPrinter.h index 6e110646a1142..0e5a17c9dcef7 100644 --- a/include/swift/AST/ASTPrinter.h +++ b/include/swift/AST/ASTPrinter.h @@ -17,6 +17,7 @@ #include "swift/Basic/QuotedString.h" #include "swift/Basic/UUID.h" #include "swift/AST/Identifier.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/DenseSet.h" #include "llvm/Support/raw_ostream.h" diff --git a/include/swift/AST/ASTTypeIDZone.def b/include/swift/AST/ASTTypeIDZone.def index 103b382e9ba50..5c1eaa91fe286 100644 --- a/include/swift/AST/ASTTypeIDZone.def +++ b/include/swift/AST/ASTTypeIDZone.def @@ -57,6 +57,7 @@ SWIFT_TYPEID_NAMED(PatternBindingEntry *, PatternBindingEntry) SWIFT_TYPEID_NAMED(PostfixOperatorDecl *, PostfixOperatorDecl) SWIFT_TYPEID_NAMED(PrecedenceGroupDecl *, PrecedenceGroupDecl) SWIFT_TYPEID_NAMED(PrefixOperatorDecl *, PrefixOperatorDecl) +SWIFT_TYPEID_NAMED(ProtocolConformance *, ProtocolConformance) SWIFT_TYPEID_NAMED(ProtocolDecl *, ProtocolDecl) SWIFT_TYPEID_NAMED(SourceFile *, SourceFile) SWIFT_TYPEID_NAMED(TypeAliasDecl *, TypeAliasDecl) diff --git a/include/swift/AST/ASTTypeIDs.h b/include/swift/AST/ASTTypeIDs.h index c4bebdfade92b..9359f95427d0e 100644 --- a/include/swift/AST/ASTTypeIDs.h +++ b/include/swift/AST/ASTTypeIDs.h @@ -52,6 +52,7 @@ struct PropertyWrapperTypeInfo; enum class CtorInitializerKind; struct PropertyWrapperLValueness; struct PropertyWrapperMutability; +class ProtocolConformance; class ProtocolDecl; class Requirement; enum class ResilienceExpansion : unsigned; diff --git a/include/swift/AST/ASTWalker.h b/include/swift/AST/ASTWalker.h index d29b3c3f60c88..4aed8fa6eabf0 100644 --- a/include/swift/AST/ASTWalker.h +++ b/include/swift/AST/ASTWalker.h @@ -37,6 +37,7 @@ enum class SemaReferenceKind : uint8_t { TypeRef, EnumElementRef, SubscriptRef, + DynamicMemberRef, }; struct ReferenceMetaData { @@ -215,12 +216,12 @@ class ASTWalker { virtual bool shouldWalkIntoLazyInitializers() { return true; } /// This method configures whether the walker should visit the body of a - /// non-single expression closure. + /// closure that was checked separately from its enclosing expression. /// /// For work that is performed for every top-level expression, this should /// be overridden to return false, to avoid duplicating work or visiting /// bodies of closures that have not yet been type checked. - virtual bool shouldWalkIntoNonSingleExpressionClosure(ClosureExpr *) { + virtual bool shouldWalkIntoSeparatelyCheckedClosure(ClosureExpr *) { return true; } diff --git a/include/swift/AST/AnyFunctionRef.h b/include/swift/AST/AnyFunctionRef.h index bc57d7ae7ba8b..da5be7c7adf91 100644 --- a/include/swift/AST/AnyFunctionRef.h +++ b/include/swift/AST/AnyFunctionRef.h @@ -123,6 +123,21 @@ class AnyFunctionRef { return cast(ACE)->getBody(); } + void setBody(BraceStmt *stmt, bool isSingleExpression) { + if (auto *AFD = TheFunction.dyn_cast()) { + AFD->setBody(stmt); + AFD->setHasSingleExpressionBody(isSingleExpression); + return; + } + + auto *ACE = TheFunction.get(); + if (auto *CE = dyn_cast(ACE)) { + return CE->setBody(stmt, isSingleExpression); + } + + llvm_unreachable("autoclosures don't have statement bodies"); + } + DeclContext *getAsDeclContext() const { if (auto *AFD = TheFunction.dyn_cast()) return AFD; diff --git a/include/swift/AST/AnyRequest.h b/include/swift/AST/AnyRequest.h index 63332fd68e7a6..c886986363e4b 100644 --- a/include/swift/AST/AnyRequest.h +++ b/include/swift/AST/AnyRequest.h @@ -22,6 +22,7 @@ #include "swift/Basic/TypeID.h" #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/Hashing.h" +#include "llvm/ADT/PointerIntPair.h" #include namespace llvm { @@ -66,6 +67,9 @@ struct AnyRequestVTable { static SourceLoc getNearestLoc(const void *ptr) { return static_cast(ptr)->getNearestLoc(); } + static bool isCached(const void *ptr) { + return static_cast(ptr)->isCached(); + } }; const uint64_t typeID; @@ -78,8 +82,29 @@ struct AnyRequestVTable { const std::function diagnoseCycle; const std::function noteCycleStep; const std::function getNearestLoc; + const std::function isCached; - template + template ::type * = nullptr> + static const AnyRequestVTable *get() { + static const AnyRequestVTable vtable = { + TypeID::value, + sizeof(Request), + &Impl::copy, + &Impl::getHash, + &Impl::deleter, + &Impl::isEqual, + &Impl::simpleDisplay, + &Impl::diagnoseCycle, + &Impl::noteCycleStep, + &Impl::getNearestLoc, + &Impl::isCached, + }; + return &vtable; + } + + template ::type * = nullptr> static const AnyRequestVTable *get() { static const AnyRequestVTable vtable = { TypeID::value, @@ -92,6 +117,7 @@ struct AnyRequestVTable { &Impl::diagnoseCycle, &Impl::noteCycleStep, &Impl::getNearestLoc, + [](auto){ return false; }, }; return &vtable; } @@ -194,6 +220,10 @@ class AnyRequestBase { return getVTable()->getNearestLoc(getRawStorage()); } + bool isCached() const { + return getVTable()->isCached(getRawStorage()); + } + /// Compare two instances for equality. friend bool operator==(const AnyRequestBase &lhs, const AnyRequestBase &rhs) { diff --git a/include/swift/AST/Attr.def b/include/swift/AST/Attr.def index 8054500c3b772..95504c3477426 100644 --- a/include/swift/AST/Attr.def +++ b/include/swift/AST/Attr.def @@ -126,7 +126,7 @@ DECL_ATTR(available, Available, CONTEXTUAL_SIMPLE_DECL_ATTR(final, Final, OnClass | OnFunc | OnAccessor | OnVar | OnSubscript | DeclModifier | - ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIStableToRemove, + ABIBreakingToAdd | ABIBreakingToRemove | APIStableToAdd | APIStableToRemove, 2) DECL_ATTR(objc, ObjC, OnAbstractFunction | OnClass | OnProtocol | OnExtension | OnVar | diff --git a/include/swift/AST/Attr.h b/include/swift/AST/Attr.h index fde3102843bd5..d6482297d272f 100644 --- a/include/swift/AST/Attr.h +++ b/include/swift/AST/Attr.h @@ -36,7 +36,6 @@ #include "swift/AST/PlatformKind.h" #include "swift/AST/Requirement.h" #include "swift/AST/TrailingCallArguments.h" -#include "swift/AST/TypeLoc.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/ErrorHandling.h" @@ -56,6 +55,7 @@ class LazyConformanceLoader; class LazyMemberLoader; class PatternBindingInitializer; class TrailingWhereClause; +class TypeExpr; /// TypeAttributes - These are attributes that may be applied to types. class TypeAttributes { @@ -1110,22 +1110,22 @@ class DynamicReplacementAttr final /// The \c @_typeEraser(TypeEraserType) attribute. class TypeEraserAttr final : public DeclAttribute { - TypeLoc TypeEraserLoc; + TypeExpr *TypeEraserExpr; LazyMemberLoader *Resolver; uint64_t ResolverContextData; friend class ResolveTypeEraserTypeRequest; - TypeEraserAttr(SourceLoc atLoc, SourceRange range, TypeLoc typeEraserLoc, + TypeEraserAttr(SourceLoc atLoc, SourceRange range, TypeExpr *typeEraserExpr, LazyMemberLoader *Resolver, uint64_t Data) : DeclAttribute(DAK_TypeEraser, atLoc, range, /*Implicit=*/false), - TypeEraserLoc(typeEraserLoc), + TypeEraserExpr(typeEraserExpr), Resolver(Resolver), ResolverContextData(Data) {} public: static TypeEraserAttr *create(ASTContext &ctx, SourceLoc atLoc, SourceRange range, - TypeLoc typeEraserLoc); + TypeExpr *typeEraserRepr); static TypeEraserAttr *create(ASTContext &ctx, LazyMemberLoader *Resolver, @@ -1133,14 +1133,10 @@ class TypeEraserAttr final : public DeclAttribute { /// Retrieve the parsed type repr for this attribute, if it /// was parsed. Else returns \c nullptr. - TypeRepr *getParsedTypeEraserTypeRepr() const { - return TypeEraserLoc.getTypeRepr(); - } + TypeRepr *getParsedTypeEraserTypeRepr() const; /// Retrieve the parsed location for this attribute, if it was parsed. - SourceLoc getLoc() const { - return TypeEraserLoc.getLoc(); - } + SourceLoc getLoc() const; /// Retrieve the resolved type of this attribute if it has been resolved by a /// successful call to \c getResolvedType(). Otherwise, @@ -1148,9 +1144,7 @@ class TypeEraserAttr final : public DeclAttribute { /// /// This entrypoint is only suitable for syntactic clients like the /// AST printer. Semantic clients should use \c getResolvedType() instead. - Type getTypeWithoutResolving() const { - return TypeEraserLoc.getType(); - } + Type getTypeWithoutResolving() const; /// Returns \c true if the type eraser type has a valid implementation of the /// erasing initializer for the given protocol. @@ -1464,25 +1458,26 @@ class SpecializeAttr : public DeclAttribute { /// The @_implements attribute, which treats a decl as the implementation for /// some named protocol requirement (but otherwise not-visible by that name). class ImplementsAttr : public DeclAttribute { - - TypeLoc ProtocolType; + TypeExpr *ProtocolType; DeclName MemberName; DeclNameLoc MemberNameLoc; public: ImplementsAttr(SourceLoc atLoc, SourceRange Range, - TypeLoc ProtocolType, + TypeExpr *ProtocolType, DeclName MemberName, DeclNameLoc MemberNameLoc); static ImplementsAttr *create(ASTContext &Ctx, SourceLoc atLoc, SourceRange Range, - TypeLoc ProtocolType, + TypeExpr *ProtocolType, DeclName MemberName, DeclNameLoc MemberNameLoc); - TypeLoc getProtocolType() const; - TypeLoc &getProtocolType(); + void setProtocolType(Type ty); + Type getProtocolType() const; + TypeRepr *getProtocolTypeRepr() const; + DeclName getMemberName() const { return MemberName; } DeclNameLoc getMemberNameLoc() const { return MemberNameLoc; } @@ -1595,7 +1590,7 @@ class ClangImporterSynthesizedTypeAttr : public DeclAttribute { /// Defines a custom attribute. class CustomAttr final : public DeclAttribute, public TrailingCallArguments { - TypeLoc type; + TypeExpr *typeExpr; Expr *arg; PatternBindingInitializer *initContext; Expr *semanticInit = nullptr; @@ -1603,19 +1598,19 @@ class CustomAttr final : public DeclAttribute, unsigned hasArgLabelLocs : 1; unsigned numArgLabels : 16; - CustomAttr(SourceLoc atLoc, SourceRange range, TypeLoc type, + CustomAttr(SourceLoc atLoc, SourceRange range, TypeExpr *type, PatternBindingInitializer *initContext, Expr *arg, ArrayRef argLabels, ArrayRef argLabelLocs, bool implicit); public: - static CustomAttr *create(ASTContext &ctx, SourceLoc atLoc, TypeLoc type, + static CustomAttr *create(ASTContext &ctx, SourceLoc atLoc, TypeExpr *type, bool implicit = false) { return create(ctx, atLoc, type, false, nullptr, SourceLoc(), { }, { }, { }, SourceLoc(), implicit); } - static CustomAttr *create(ASTContext &ctx, SourceLoc atLoc, TypeLoc type, + static CustomAttr *create(ASTContext &ctx, SourceLoc atLoc, TypeExpr *type, bool hasInitializer, PatternBindingInitializer *initContext, SourceLoc lParenLoc, @@ -1628,8 +1623,8 @@ class CustomAttr final : public DeclAttribute, unsigned getNumArguments() const { return numArgLabels; } bool hasArgumentLabelLocs() const { return hasArgLabelLocs; } - TypeLoc &getTypeLoc() { return type; } - const TypeLoc &getTypeLoc() const { return type; } + TypeRepr *getTypeRepr() const; + Type getType() const; Expr *getArg() const { return arg; } void setArg(Expr *newArg) { arg = newArg; } @@ -1642,6 +1637,14 @@ class CustomAttr final : public DeclAttribute, static bool classof(const DeclAttribute *DA) { return DA->getKind() == DAK_Custom; } + +private: + friend class CustomAttrNominalRequest; + void resetTypeInformation(TypeExpr *repr); + +private: + friend class CustomAttrTypeRequest; + void setType(Type ty); }; /// Relates a property to its projection value property, as described by a property wrapper. For diff --git a/include/swift/AST/AutoDiff.h b/include/swift/AST/AutoDiff.h index ffd3919bdd6bd..5b447027b20c5 100644 --- a/include/swift/AST/AutoDiff.h +++ b/include/swift/AST/AutoDiff.h @@ -173,18 +173,21 @@ enum class AutoDiffGeneratedDeclarationKind : uint8_t { }; /// SIL-level automatic differentiation indices. Consists of: -/// - Parameter indices: indices of parameters to differentiate with respect to. -/// - Result index: index of the result to differentiate from. +/// - The differentiability parameter indices. +/// - The differentiability result indices. // TODO(TF-913): Remove `SILAutoDiffIndices` in favor of `AutoDiffConfig`. -// `AutoDiffConfig` supports multiple result indices. +// `AutoDiffConfig` additionally stores a derivative generic signature. struct SILAutoDiffIndices { - /// The index of the dependent result to differentiate from. - unsigned source; - /// The indices for independent parameters to differentiate with respect to. + /// The indices of independent parameters to differentiate with respect to. IndexSubset *parameters; + /// The indices of dependent results to differentiate from. + IndexSubset *results; - /*implicit*/ SILAutoDiffIndices(unsigned source, IndexSubset *parameters) - : source(source), parameters(parameters) {} + /*implicit*/ SILAutoDiffIndices(IndexSubset *parameters, IndexSubset *results) + : parameters(parameters), results(results) { + assert(parameters && "Parameter indices must be non-null"); + assert(results && "Result indices must be non-null"); + } bool operator==(const SILAutoDiffIndices &other) const; @@ -202,7 +205,12 @@ struct SILAutoDiffIndices { SWIFT_DEBUG_DUMP; std::string mangle() const { - std::string result = "src_" + llvm::utostr(source) + "_wrt_"; + std::string result = "src_"; + interleave( + results->getIndices(), + [&](unsigned idx) { result += llvm::utostr(idx); }, + [&] { result += '_'; }); + result += "_wrt_"; llvm::interleave( parameters->getIndices(), [&](unsigned idx) { result += llvm::utostr(idx); }, @@ -513,8 +521,8 @@ IndexSubset *getLoweredParameterIndices(IndexSubset *astParameterIndices, /// /// Returns the "constrained" derivative/transpose generic signature given: /// - An original SIL function type. -/// - Differentiability parameter indices. -/// - A possibly "unconstrained" derivative generic signature. +/// - Differentiability/linearity parameter indices. +/// - A possibly "unconstrained" derivative/transpose generic signature. GenericSignature getConstrainedDerivativeGenericSignature( SILFunctionType *originalFnTy, IndexSubset *diffParamIndices, GenericSignature derivativeGenSig, LookupConformanceFn lookupConformance, diff --git a/include/swift/AST/CaptureInfo.h b/include/swift/AST/CaptureInfo.h index 6d2eb20735229..4203c80eaf338 100644 --- a/include/swift/AST/CaptureInfo.h +++ b/include/swift/AST/CaptureInfo.h @@ -22,7 +22,6 @@ #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/Support/TrailingObjects.h" -#include namespace swift { class CapturedValue; diff --git a/include/swift/AST/ConcreteDeclRef.h b/include/swift/AST/ConcreteDeclRef.h index 9049e438e245a..1ef420d98248f 100644 --- a/include/swift/AST/ConcreteDeclRef.h +++ b/include/swift/AST/ConcreteDeclRef.h @@ -21,7 +21,6 @@ #include "swift/Basic/LLVM.h" #include "swift/AST/SubstitutionMap.h" #include "swift/AST/TypeAlignments.h" -#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/Support/Compiler.h" #include diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h index eb6af822e7ab7..600042bf07563 100644 --- a/include/swift/AST/Decl.h +++ b/include/swift/AST/Decl.h @@ -41,7 +41,6 @@ #include "swift/Basic/OptionalEnum.h" #include "swift/Basic/Range.h" #include "swift/Basic/Located.h" -#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/Support/TrailingObjects.h" #include @@ -2716,6 +2715,7 @@ class ValueDecl : public Decl { /// Is this declaration marked with 'dynamic'? bool isDynamic() const; +private: bool isObjCDynamic() const { return isObjC() && isDynamic(); } @@ -2724,6 +2724,37 @@ class ValueDecl : public Decl { return !isObjC() && isDynamic(); } + bool isObjCDynamicInGenericClass() const; + +public: + /// Should we use Objective-C method dispatch for this decl. + bool shouldUseObjCDispatch() const { + return isObjCDynamic(); + } + + /// Should we use native dynamic function replacement dispatch for this decl. + bool shouldUseNativeDynamicDispatch() const { + return isNativeDynamic(); + } + + /// Should we use Objective-C category based function replacement for this + /// decl. + /// This is all `@objc dynamic` methods except for such methods in native + /// generic classes. We can't use a category for generic classes so we use + /// native replacement instead (this behavior is only enabled with + /// -enable-implicit-dynamic). + bool shouldUseObjCMethodReplacement() const; + + /// Should we use native dynamic function replacement mechanism for this decl. + /// This is all native dynamic methods except for `@objc dynamic` methods in + /// generic classes (see above). + bool shouldUseNativeMethodReplacement() const; + + /// Is this a native dynamic function replacement based replacement. + /// This is all @_dynamicReplacement(for:) of native functions and @objc + /// dynamic methods on generic classes (see above). + bool isNativeMethodReplacement() const; + bool isEffectiveLinkageMoreVisibleThan(ValueDecl *other) const { return (std::min(getEffectiveAccess(), AccessLevel::Public) > std::min(other->getEffectiveAccess(), AccessLevel::Public)); @@ -3569,6 +3600,8 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext { /// initializer. bool hasDefaultInitializer() const; + bool isTypeErasedGenericClass() const; + /// Retrieves the synthesized zero parameter default initializer for this /// declaration, or \c nullptr if it doesn't have one. ConstructorDecl *getDefaultInitializer() const; @@ -4117,8 +4150,8 @@ class ClassDecl final : public NominalTypeDecl { /// /// \param isInstance Whether we are looking for an instance method /// (vs. a class method). - MutableArrayRef lookupDirect(ObjCSelector selector, - bool isInstance); + TinyPtrVector lookupDirect(ObjCSelector selector, + bool isInstance); /// Record the presence of an @objc method with the given selector. void recordObjCMethod(AbstractFunctionDecl *method, ObjCSelector selector); @@ -5232,6 +5265,12 @@ class VarDecl : public AbstractStorageDecl { Optional getPropertyWrapperMutability() const; + /// Returns whether this property is the backing storage property or a storage + /// wrapper for wrapper instance's projectedValue. If this property is + /// neither, then it returns `None`. + Optional + getPropertyWrapperSynthesizedPropertyKind() const; + /// Retrieve the backing storage property for a property that has an /// attached property wrapper. /// @@ -7048,6 +7087,10 @@ class PrecedenceGroupDecl : public Decl { return Name; } + // This is needed to allow templated code to work with both ValueDecls and + // PrecedenceGroupDecls. + DeclBaseName getBaseName() const { return Name; } + SourceLoc getLBraceLoc() const { return LBraceLoc; } SourceLoc getRBraceLoc() const { return RBraceLoc; } @@ -7205,6 +7248,10 @@ class OperatorDecl : public Decl { SourceLoc getNameLoc() const { return NameLoc; } Identifier getName() const { return name; } + // This is needed to allow templated code to work with both ValueDecls and + // OperatorDecls. + DeclBaseName getBaseName() const { return name; } + /// Get the list of identifiers after the colon in the operator declaration. /// /// This list includes the names of designated types. For infix operators, the @@ -7265,12 +7312,6 @@ class InfixOperatorDecl : public OperatorDecl { PrecedenceGroupDecl *getPrecedenceGroup() const; - /// True if this decl's attributes conflict with those declared by another - /// operator. - bool conflictsWith(InfixOperatorDecl *other) { - return getPrecedenceGroup() != other->getPrecedenceGroup(); - } - static bool classof(const Decl *D) { return D->getKind() == DeclKind::InfixOperator; } @@ -7299,12 +7340,6 @@ class PrefixOperatorDecl : public OperatorDecl { return { getOperatorLoc(), getNameLoc() }; } - /// True if this decl's attributes conflict with those declared by another - /// PrefixOperatorDecl. - bool conflictsWith(PrefixOperatorDecl *other) { - return false; - } - static bool classof(const Decl *D) { return D->getKind() == DeclKind::PrefixOperator; } @@ -7332,12 +7367,6 @@ class PostfixOperatorDecl : public OperatorDecl { SourceRange getSourceRange() const { return { getOperatorLoc(), getNameLoc() }; } - - /// True if this decl's attributes conflict with those declared by another - /// PostfixOperatorDecl. - bool conflictsWith(PostfixOperatorDecl *other) { - return false; - } static bool classof(const Decl *D) { return D->getKind() == DeclKind::PostfixOperator; diff --git a/include/swift/AST/DeclContext.h b/include/swift/AST/DeclContext.h index ae57b1ad9eb0e..36e1f07a2db56 100644 --- a/include/swift/AST/DeclContext.h +++ b/include/swift/AST/DeclContext.h @@ -55,6 +55,9 @@ namespace swift { class GenericSignature; class GenericTypeParamDecl; class GenericTypeParamType; + class InfixOperatorDecl; + class InfixOperatorLookupResult; + class PrecedenceGroupDecl; class ProtocolDecl; class Requirement; class SourceFile; @@ -62,6 +65,9 @@ namespace swift { class ModuleDecl; class GenericTypeDecl; class NominalTypeDecl; + class PrecedenceGroupLookupResult; + class PostfixOperatorDecl; + class PrefixOperatorDecl; class ProtocolConformance; class ValueDecl; class Initializer; @@ -562,6 +568,29 @@ class alignas(1 << DeclContextAlignInBits) DeclContext { ObjCSelector selector, SmallVectorImpl &results) const; + /// Looks up an infix operator with a given \p name. + /// + /// This returns a vector of results, as it's possible to find multiple infix + /// operators with different precedence groups. + InfixOperatorLookupResult lookupInfixOperator(Identifier name) const; + + /// Looks up an prefix operator with a given \p name. + /// + /// If multiple results are found, one is chosen in a stable manner, as + /// prefix operator decls cannot differ other than in name. If no results are + /// found, returns \c nullptr. + PrefixOperatorDecl *lookupPrefixOperator(Identifier name) const; + + /// Looks up an postfix operator with a given \p name. + /// + /// If multiple results are found, one is chosen in a stable manner, as + /// postfix operator decls cannot differ other than in name. If no results are + /// found, returns \c nullptr. + PostfixOperatorDecl *lookupPostfixOperator(Identifier name) const; + + /// Looks up a precedence group with a given \p name. + PrecedenceGroupLookupResult lookupPrecedenceGroup(Identifier name) const; + /// Return the ASTContext for a specified DeclContext by /// walking up to the enclosing module and returning its ASTContext. LLVM_READONLY @@ -813,7 +842,10 @@ class IterableDeclContext { const Decl *getDecl() const; /// Return 'this' as a \c GenericContext. - const GenericContext *getAsGenericContext() const; + GenericContext *getAsGenericContext(); + const GenericContext *getAsGenericContext() const { + return const_cast(this)->getAsGenericContext(); + } /// Get the DeclID this Decl was deserialized from. serialization::DeclID getDeclID() const { diff --git a/include/swift/AST/DiagnosticsCommon.def b/include/swift/AST/DiagnosticsCommon.def index b633d8d686bd6..d797125013ed3 100644 --- a/include/swift/AST/DiagnosticsCommon.def +++ b/include/swift/AST/DiagnosticsCommon.def @@ -159,11 +159,11 @@ NOTE(circular_type_resolution_note,none, // MARK: Cross-import overlay loading diagnostics //------------------------------------------------------------------------------ ERROR(cannot_load_swiftoverlay_file, none, - "cannot load cross-import overlay for %0 and %1: %2 (declared by '%3')", - (Identifier, Identifier, StringRef, StringRef)) + "cannot load cross-import overlay for '%0' and '%1': %2 (declared by '%3')", + (StringRef, StringRef, StringRef, StringRef)) ERROR(cannot_list_swiftcrossimport_dir, none, - "cannot list cross-import overlays for %0: %1 (declared in '%2')", - (Identifier, StringRef, StringRef)) + "cannot list cross-import overlays for '%0': %1 (declared in '%2')", + (StringRef, StringRef, StringRef)) WARNING(cross_imported_by_both_modules, none, "modules %0 and %1 both declare module %2 as a cross-import overlay, " "which may cause paradoxical behavior when looking up names in them; " diff --git a/include/swift/AST/DiagnosticsFrontend.def b/include/swift/AST/DiagnosticsFrontend.def index 4f72e3e17a7bb..7aa018966646b 100644 --- a/include/swift/AST/DiagnosticsFrontend.def +++ b/include/swift/AST/DiagnosticsFrontend.def @@ -234,6 +234,10 @@ WARNING(tbd_only_supported_in_whole_module,none, "TBD generation is only supported when the whole module can be seen", ()) +ERROR(tbd_not_supported_with_cmo,none, + "Test-Based InstallAPI (TBD) is not support with cross-module-optimization", + ()) + WARNING(linker_directives_choice_confusion,none, "only one of -emit-ldadd-cfile-path and -module-installname-map-file can be specified;" "the c file won't be generated", @@ -322,6 +326,8 @@ ERROR(error_extracting_version_from_module_interface,none, ERROR(unsupported_version_of_module_interface,none, "unsupported version of module interface '%0': '%1'", (StringRef, llvm::VersionTuple)) +ERROR(error_opening_explicit_module_file,none, + "failed to open explicit Swift module: %0", (StringRef)) ERROR(error_extracting_flags_from_module_interface,none, "error extracting flags from module interface", ()) REMARK(rebuilding_module_from_interface,none, diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index deeec88026f09..d12b61b251394 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -94,6 +94,9 @@ ERROR(could_not_find_enum_case,none, NOTE(did_you_mean_raw_type,none, "did you mean to specify a raw type on the enum declaration?", ()) + +NOTE(did_you_mean_generic_param_as_conformance,none, + "did you mean to declare %0 as a protocol conformance for %1?", (DeclName, Type)) NOTE(any_as_anyobject_fixit, none, "cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members", ()) @@ -557,6 +560,9 @@ ERROR(expr_keypath_mutating_getter,none, ERROR(expr_keypath_static_member,none, "%select{key path|dynamic key path member lookup}1 cannot refer to static member %0", (DeclName, bool)) +ERROR(expr_keypath_enum_case,none, + "%select{key path|dynamic key path member lookup}1 cannot refer to enum case %0", + (DeclName, bool)) ERROR(expr_keypath_empty,none, "empty key path does not refer to a property", ()) ERROR(expr_unsupported_objc_key_path_component,none, @@ -760,12 +766,20 @@ ERROR(invalid_redecl,none,"invalid redeclaration of %0", (DeclName)) ERROR(invalid_redecl_init,none, "invalid redeclaration of synthesized %select{|memberwise }1%0", (DeclName, bool)) +ERROR(invalid_redecl_implicit,none, + "invalid redeclaration of synthesized " + "%select{%0|implementation for protocol requirement}1 %2", + (DescriptiveDeclKind, bool, DeclName)) WARNING(invalid_redecl_swift5_warning,none, "redeclaration of %0 is deprecated and will be an error in Swift 5", (DeclName)) NOTE(invalid_redecl_prev,none, "%0 previously declared here", (DeclName)) +NOTE(invalid_redecl_implicit_wrapper,none, + "%0 synthesized for property wrapper " + "%select{projected value|backing storage}1", + (DeclName, bool)) ERROR(ambiguous_type_base,none, "%0 is ambiguous for type lookup in this context", (DeclNameRef)) @@ -2753,10 +2767,10 @@ WARNING(differentiable_nondiff_type_implicit_noderivative_fixit,none, /*nominalCanDeriveAdditiveArithmetic*/ bool)) WARNING(differentiable_immutable_wrapper_implicit_noderivative_fixit,none, "synthesis of the 'Differentiable.move(along:)' requirement for %1 " - "requires all stored properties not marked with `@noDerivative` to be " - "mutable; add an explicit '@noDerivative' attribute" + "requires 'wrappedValue' in property wrapper %0 to be mutable; " + "add an explicit '@noDerivative' attribute" "%select{|, or conform %1 to 'AdditiveArithmetic'}2", - (/*wrapperType*/ StringRef, /*nominalName*/ Identifier, + (/*wrapperType*/ Identifier, /*nominalName*/ Identifier, /*nominalCanDeriveAdditiveArithmetic*/ bool)) WARNING(differentiable_let_property_implicit_noderivative_fixit,none, "synthesis of the 'Differentiable.move(along:)' requirement for %0 " @@ -5058,6 +5072,14 @@ NOTE(function_builder_remove_attr, none, "remove the attribute to explicitly disable the function builder", ()) NOTE(function_builder_remove_returns, none, "remove 'return' statements to apply the function builder", ()) +ERROR(function_builder_infer_ambig, none, + "ambiguous function builder inferred for %0: %1 or %2", + (DeclName, Type, Type)) +NOTE(function_builder_infer_add_return, none, + "add an explicit 'return' statement to not use a function builder", ()) +NOTE(function_builder_infer_pick_specific, none, + "apply function builder %0 (inferred from %select{protocol|dynamic replacement of}1 %2)", + (Type, unsigned, DeclName)) //------------------------------------------------------------------------------ // MARK: Tuple Shuffle Diagnostics diff --git a/include/swift/AST/Evaluator.h b/include/swift/AST/Evaluator.h index 59de0280e6869..5235343ebe779 100644 --- a/include/swift/AST/Evaluator.h +++ b/include/swift/AST/Evaluator.h @@ -225,7 +225,7 @@ class Evaluator { /// so all clients must cope with cycles. llvm::DenseMap> dependencies; - evaluator::DependencyCollector collector; + evaluator::DependencyRecorder recorder; /// Retrieve the request function for the given zone and request IDs. AbstractRequestFunction *getAbstractRequestFunction(uint8_t zoneID, @@ -243,10 +243,7 @@ class Evaluator { public: /// Construct a new evaluator that can emit cyclic-dependency /// diagnostics through the given diagnostics engine. - Evaluator(DiagnosticEngine &diags, - bool debugDumpCycles, - bool buildDependencyGraph, - bool enableExperimentalPrivateDeps); + Evaluator(DiagnosticEngine &diags, const LangOptions &opts); /// Emit GraphViz output visualizing the request graph. void emitRequestEvaluatorGraphViz(llvm::StringRef graphVizPath); @@ -262,14 +259,20 @@ class Evaluator { void registerRequestFunctions(Zone zone, ArrayRef functions); + void enumerateReferencesInFile( + const SourceFile *SF, + evaluator::DependencyRecorder::ReferenceEnumerator f) const { + return recorder.enumerateReferencesInFile(SF, f); + } + /// Retrieve the result produced by evaluating a request that can /// be cached. template::type * = nullptr> llvm::Expected operator()(const Request &request) { - evaluator::DependencyCollector::StackRAII incDeps{collector, - request}; + evaluator::DependencyRecorder::StackRAII incDeps{recorder, + request}; // The request can be cached, but check a predicate to determine // whether this particular instance is cached. This allows more // fine-grained control over which instances get cache. @@ -285,8 +288,8 @@ class Evaluator { typename std::enable_if::type * = nullptr> llvm::Expected operator()(const Request &request) { - evaluator::DependencyCollector::StackRAII incDeps{collector, - request}; + evaluator::DependencyRecorder::StackRAII incDeps{recorder, + request}; return getResultUncached(request); } @@ -431,19 +434,22 @@ class Evaluator { } private: - // Report the result of evaluating a request that is not a dependency sink - - // which is to say do nothing. - template ::type * = nullptr> + // Report the result of evaluating a request that is not a dependency sink. + template ::type * = nullptr> void reportEvaluatedResult(const Request &r, - const typename Request::OutputType &o) {} + const typename Request::OutputType &o) { + recorder.replay(activeRequests, ActiveRequest(r)); + } // Report the result of evaluating a request that is a dependency sink. template ::type * = nullptr> void reportEvaluatedResult(const Request &r, const typename Request::OutputType &o) { - r.writeDependencySink(collector, o); + return recorder.record(activeRequests, [&r, &o](auto &c) { + return r.writeDependencySink(c, o); + }); } public: diff --git a/include/swift/AST/EvaluatorDependencies.h b/include/swift/AST/EvaluatorDependencies.h index ceb16440c67bf..7808e86caa9cc 100644 --- a/include/swift/AST/EvaluatorDependencies.h +++ b/include/swift/AST/EvaluatorDependencies.h @@ -18,6 +18,7 @@ #ifndef SWIFT_AST_EVALUATOR_DEPENDENCIES_H #define SWIFT_AST_EVALUATOR_DEPENDENCIES_H +#include "swift/AST/AnyRequest.h" #include "swift/AST/AttrKind.h" #include "swift/AST/SourceFile.h" #include "llvm/ADT/PointerIntPair.h" @@ -106,30 +107,95 @@ inline DependencyScope getScopeForAccessLevel(AccessLevel l) { // of individual contexts. using DependencySource = llvm::PointerIntPair; -/// A \c DependencyCollector is an aggregator of named references discovered in a -/// particular \c DependencyScope during the course of request evaluation. +struct DependencyRecorder; + +/// A \c DependencyCollector defines an abstract write-only buffer of +/// \c Reference objects. References are added to a collector during the write +/// phase of request evaluation (in \c writeDependencySink) with the various +/// \c add* functions below.. +/// +/// A \c DependencyCollector cannot be created directly. You must invoke +/// \c DependencyRecorder::record, which will wire a dependency collector into +/// the provided continuation block. struct DependencyCollector { -private: - /// A stack of dependency sources in the order they were evaluated. - llvm::SmallVector dependencySources; + friend DependencyRecorder; -public: - enum class Mode { - // Enables the current "status quo" behavior of the dependency collector. - // - // By default, the dependency collector moves to register dependencies in - // the referenced name trackers at the top of the active dependency stack. - StatusQuo, - // Enables an experimental mode to only register private dependencies. - // - // This mode restricts the dependency collector to ignore changes of - // scope. This has practical effect of charging all unqualified lookups to - // the primary file being acted upon instead of to the destination file. - ExperimentalPrivateDependencies, + struct Reference { + public: + enum class Kind { + Empty, + Tombstone, + UsedMember, + PotentialMember, + TopLevel, + Dynamic, + } kind; + + NominalTypeDecl *subject; + DeclBaseName name; + bool cascades; + + private: + Reference(Kind kind, NominalTypeDecl *subject, DeclBaseName name, + bool cascades) + : kind(kind), subject(subject), name(name), cascades(cascades) {} + + public: + static Reference empty() { + return {Kind::Empty, llvm::DenseMapInfo::getEmptyKey(), + llvm::DenseMapInfo::getEmptyKey(), false}; + } + + static Reference tombstone() { + return {Kind::Tombstone, + llvm::DenseMapInfo::getTombstoneKey(), + llvm::DenseMapInfo::getTombstoneKey(), false}; + } + + public: + static Reference usedMember(NominalTypeDecl *subject, DeclBaseName name, + bool cascades) { + return {Kind::UsedMember, subject, name, cascades}; + } + + static Reference potentialMember(NominalTypeDecl *subject, bool cascades) { + return {Kind::PotentialMember, subject, DeclBaseName(), cascades}; + } + + static Reference topLevel(DeclBaseName name, bool cascades) { + return {Kind::TopLevel, nullptr, name, cascades}; + } + + static Reference dynamic(DeclBaseName name, bool cascades) { + return {Kind::Dynamic, nullptr, name, cascades}; + } + + public: + struct Info { + static inline Reference getEmptyKey() { return Reference::empty(); } + static inline Reference getTombstoneKey() { + return Reference::tombstone(); + } + static inline unsigned getHashValue(const Reference &Val) { + return llvm::hash_combine(Val.kind, Val.subject, + Val.name.getAsOpaquePointer()); + } + static bool isEqual(const Reference &LHS, const Reference &RHS) { + return LHS.kind == RHS.kind && LHS.subject == RHS.subject && + LHS.name == RHS.name; + } + }; }; - Mode mode; - explicit DependencyCollector(Mode mode) : mode{mode} {}; +public: + using ReferenceSet = llvm::DenseSet; + +private: + DependencyRecorder &parent; + ReferenceSet scratch; + +public: + explicit DependencyCollector(DependencyRecorder &parent) : parent(parent) {} public: /// Registers a named reference from the current dependency scope to a member @@ -168,6 +234,109 @@ struct DependencyCollector { /// a name that is found by \c AnyObject lookup. void addDynamicLookupName(DeclBaseName name); +public: + /// Retrieves the dependency recorder that created this dependency collector. + const DependencyRecorder &getRecorder() const { return parent; } + + /// Returns \c true if this collector has not accumulated + /// any \c Reference objects. + bool empty() const { return scratch.empty(); } +}; + +/// A \c DependencyRecorder is an aggregator of named references discovered in a +/// particular \c DependencyScope during the course of request evaluation. +struct DependencyRecorder { + friend DependencyCollector; + + enum class Mode { + // Enables the status quo of recording direct dependencies. + // + // This mode restricts the dependency collector to ignore changes of + // scope. This has practical effect of charging all unqualified lookups to + // the primary file being acted upon instead of to the destination file. + DirectDependencies, + // Enables a legacy mode of dependency tracking that makes a distinction + // between private and cascading edges, and does not directly capture + // transitive dependencies. + // + // By default, the dependency collector moves to register dependencies in + // the referenced name trackers at the top of the active dependency stack. + LegacyCascadingDependencies, + }; + +private: + /// A stack of dependency sources in the order they were evaluated. + llvm::SmallVector dependencySources; + llvm::DenseMap + fileReferences; + llvm::DenseMap + requestReferences; + Mode mode; + bool isRecording; + +public: + explicit DependencyRecorder(Mode mode) : mode{mode}, isRecording{false} {}; + +private: + /// Records the given \c Reference as a dependency of the current dependency + /// source. + /// + /// This is as opposed to merely collecting a \c Reference, which may just buffer + /// it for realization or replay later. + void realize(const DependencyCollector::Reference &ref); + +public: + /// Begins the recording of references by invoking the given continuation + /// with a fresh \c DependencyCollector object. This object should be used + /// to buffer dependency-relevant references to names looked up by a + /// given request. + /// + /// Recording only occurs for requests that are dependency sinks. + void record(const llvm::SetVector &stack, + llvm::function_ref rec); + + /// Replays the \c Reference objects collected by a given cached request and + /// its sub-requests into the current dependency scope. + /// + /// Dependency replay ensures that cached requests do not "hide" names from + /// the active dependency scope. This would otherwise occur frequently in + /// batch mode, where cached requests effectively block the re-evaluation of + /// a large quantity of computations that perform name lookups by design. + /// + /// Replay need only occur for requests that are (separately) cached. + void replay(const llvm::SetVector &stack, + const swift::ActiveRequest &req); +private: + /// Given the current stack of requests and a buffer of \c Reference objects + /// walk the active stack looking for the next-innermost cached request. If + /// found, insert the buffer of references into that request's known reference + /// set. + /// + /// This algorithm ensures that references propagate lazily up the request + /// graph from cached sub-requests to their cached parents. Once this process + /// completes, all cached requests in the request graph will see the + /// union of all references recorded while evaluating their sub-requests. + /// + /// This algorithm *must* be tail-called during + /// \c DependencyRecorder::record or \c DependencyRecorder::replay + /// or the corresponding set of references for the active dependency scope + /// will become incoherent. + void + unionNearestCachedRequest(ArrayRef stack, + const DependencyCollector::ReferenceSet &scratch); + +public: + using ReferenceEnumerator = + llvm::function_ref; + + /// Enumerates the set of references associated with a given source file, + /// passing them to the given enumeration callback. + /// + /// The order of enumeration is completely undefined. It is the responsibility + /// of callers to ensure they are order-invariant or are sorting the result. + void enumerateReferencesInFile(const SourceFile *SF, + ReferenceEnumerator f) const ; + public: /// Returns the scope of the current active scope. /// @@ -189,7 +358,12 @@ struct DependencyCollector { SourceFile *getActiveDependencySourceOrNull() const { if (dependencySources.empty()) return nullptr; - return dependencySources.back().getPointer(); + switch (mode) { + case Mode::LegacyCascadingDependencies: + return dependencySources.back().getPointer(); + case Mode::DirectDependencies: + return dependencySources.front().getPointer(); + } } public: @@ -197,14 +371,14 @@ struct DependencyCollector { /// dependency source stack. It is specialized to be zero-cost for /// requests that are not dependency sources. template > struct StackRAII { - StackRAII(DependencyCollector &DC, const Request &Req) {} + StackRAII(DependencyRecorder &DR, const Request &Req) {} }; template struct StackRAII::type> { - NullablePtr Coll; - StackRAII(DependencyCollector &coll, const Request &Req) { + NullablePtr Coll; + StackRAII(DependencyRecorder &coll, const Request &Req) { auto Source = Req.readDependencySource(coll); // If there is no source to introduce, bail. This can occur if // a request originates in the context of a module. @@ -222,41 +396,14 @@ struct DependencyCollector { }; private: - /// Returns the first dependency source registered with the tracker, or - /// \c nullptr if no dependency sources have been registered. - SourceFile *getFirstDependencySourceOrNull() const { - if (dependencySources.empty()) - return nullptr; - return dependencySources.front().getPointer(); - } - - /// If there is an active dependency source, returns its - /// \c ReferencedNameTracker. Else, returns \c nullptr. - ReferencedNameTracker *getActiveDependencyTracker() const { - SourceFile *source = nullptr; - switch (mode) { - case Mode::StatusQuo: - source = getActiveDependencySourceOrNull(); - break; - case Mode::ExperimentalPrivateDependencies: - source = getFirstDependencySourceOrNull(); - break; - } - - if (!source) - return nullptr; - - return source->getRequestBasedReferencedNameTracker(); - } - /// Returns \c true if the scope of the current active source cascades. /// /// If there is no active scope, the result always cascades. bool isActiveSourceCascading() const { switch (mode) { - case Mode::StatusQuo: + case Mode::LegacyCascadingDependencies: return getActiveSourceScope() == evaluator::DependencyScope::Cascading; - case Mode::ExperimentalPrivateDependencies: + case Mode::DirectDependencies: return false; } llvm_unreachable("invalid mode"); diff --git a/include/swift/AST/ExistentialLayout.h b/include/swift/AST/ExistentialLayout.h index 50f0cca77ca15..9f08d03cf8101 100644 --- a/include/swift/AST/ExistentialLayout.h +++ b/include/swift/AST/ExistentialLayout.h @@ -20,7 +20,6 @@ #include "swift/Basic/ArrayRefView.h" #include "swift/AST/ASTContext.h" #include "swift/AST/Type.h" -#include "llvm/ADT/SmallVector.h" namespace swift { class ProtocolDecl; diff --git a/include/swift/AST/Expr.h b/include/swift/AST/Expr.h index 9168f0583e618..1cb0976cdfd5e 100644 --- a/include/swift/AST/Expr.h +++ b/include/swift/AST/Expr.h @@ -25,7 +25,6 @@ #include "swift/AST/ProtocolConformanceRef.h" #include "swift/AST/TrailingCallArguments.h" #include "swift/AST/TypeAlignments.h" -#include "swift/AST/TypeLoc.h" #include "swift/AST/Availability.h" #include "swift/Basic/Debug.h" #include "swift/Basic/InlineBitfield.h" @@ -555,7 +554,7 @@ class alignas(8) Expr { SWIFT_DEBUG_DUMP; void dump(raw_ostream &OS, unsigned Indent = 0) const; void dump(raw_ostream &OS, llvm::function_ref getType, - llvm::function_ref getTypeOfTypeLoc, + llvm::function_ref getTypeOfTypeRepr, llvm::function_ref getTypeOfKeyPathComponent, unsigned Indent = 0) const; @@ -598,13 +597,23 @@ class ErrorExpr : public Expr { /// CodeCompletionExpr - Represents the code completion token in the AST, this /// can help us preserve the context of the code completion position. class CodeCompletionExpr : public Expr { - SourceRange Range; + Expr *Base; + SourceLoc Loc; public: - CodeCompletionExpr(SourceRange Range, Type Ty = Type()) - : Expr(ExprKind::CodeCompletion, /*Implicit=*/true, Ty), Range(Range) {} + CodeCompletionExpr(Expr *Base, SourceLoc Loc) + : Expr(ExprKind::CodeCompletion, /*Implicit=*/true, Type()), + Base(Base), Loc(Loc) {} - SourceRange getSourceRange() const { return Range; } + CodeCompletionExpr(SourceLoc Loc) + : CodeCompletionExpr(/*Base=*/nullptr, Loc) {} + + Expr *getBase() const { return Base; } + void setBase(Expr *E) { Base = E; } + + SourceLoc getLoc() const { return Loc; } + SourceLoc getStartLoc() const { return Base ? Base->getStartLoc() : Loc; } + SourceLoc getEndLoc() const { return Loc; } static bool classof(const Expr *E) { return E->getKind() == ExprKind::CodeCompletion; @@ -3770,11 +3779,8 @@ class ClosureExpr : public AbstractClosureExpr { /// the CaptureListExpr which would normally maintain this sort of /// information about captured variables), we need to have some way to access /// this information directly on the ClosureExpr. - /// - /// The bit indicates whether this closure has had a function builder - /// applied to it. - llvm::PointerIntPair CapturedSelfDeclAndAppliedBuilder; - + VarDecl * CapturedSelfDecl; + /// The location of the "throws", if present. SourceLoc ThrowsLoc; @@ -3786,7 +3792,8 @@ class ClosureExpr : public AbstractClosureExpr { SourceLoc InLoc; /// The explicitly-specified result type. - TypeExpr *ExplicitResultType; + llvm::PointerIntPair + ExplicitResultTypeAndSeparatelyChecked; /// The body of the closure, along with a bit indicating whether it /// was originally just a single expression. @@ -3799,9 +3806,10 @@ class ClosureExpr : public AbstractClosureExpr { : AbstractClosureExpr(ExprKind::Closure, Type(), /*Implicit=*/false, discriminator, parent), BracketRange(bracketRange), - CapturedSelfDeclAndAppliedBuilder(capturedSelfDecl, false), + CapturedSelfDecl(capturedSelfDecl), ThrowsLoc(throwsLoc), ArrowLoc(arrowLoc), InLoc(inLoc), - ExplicitResultType(explicitResultType), Body(nullptr) { + ExplicitResultTypeAndSeparatelyChecked(explicitResultType, false), + Body(nullptr) { setParameterList(params); Bits.ClosureExpr.HasAnonymousClosureVars = false; } @@ -3855,13 +3863,15 @@ class ClosureExpr : public AbstractClosureExpr { Type getExplicitResultType() const { assert(hasExplicitResultType() && "No explicit result type"); - return ExplicitResultType->getInstanceType(); + return ExplicitResultTypeAndSeparatelyChecked.getPointer() + ->getInstanceType(); } void setExplicitResultType(Type ty); TypeRepr *getExplicitResultTypeRepr() const { assert(hasExplicitResultType() && "No explicit result type"); - return ExplicitResultType->getTypeRepr(); + return ExplicitResultTypeAndSeparatelyChecked.getPointer() + ->getTypeRepr(); } /// Determine whether the closure has a single expression for its @@ -3890,19 +3900,12 @@ class ClosureExpr : public AbstractClosureExpr { /// Only valid when \c hasSingleExpressionBody() is true. Expr *getSingleExpressionBody() const; - /// Set the body for a closure that has a single expression as its - /// body. - /// - /// This routine cannot change whether a closure has a single expression as - /// its body; it can only update that expression. - void setSingleExpressionBody(Expr *NewBody); - /// Is this a completely empty closure? bool hasEmptyBody() const; /// VarDecl captured by this closure under the literal name \c self , if any. VarDecl *getCapturedSelfDecl() const { - return CapturedSelfDeclAndAppliedBuilder.getPointer(); + return CapturedSelfDecl; } /// Whether this closure captures the \c self param in its body in such a @@ -3910,12 +3913,14 @@ class ClosureExpr : public AbstractClosureExpr { /// captured non-weakly). bool capturesSelfEnablingImplictSelf() const; - bool hasAppliedFunctionBuilder() const { - return CapturedSelfDeclAndAppliedBuilder.getInt(); + /// Whether this closure's body was type checked separately from its + /// enclosing expression. + bool wasSeparatelyTypeChecked() const { + return ExplicitResultTypeAndSeparatelyChecked.getInt(); } - void setAppliedFunctionBuilder(bool flag = true) { - CapturedSelfDeclAndAppliedBuilder.setInt(flag); + void setSeparatelyTypeChecked(bool flag = true) { + ExplicitResultTypeAndSeparatelyChecked.setInt(flag); } static bool classof(const Expr *E) { @@ -4591,23 +4596,22 @@ class DotSyntaxBaseIgnoredExpr : public Expr { class ExplicitCastExpr : public Expr { Expr *SubExpr; SourceLoc AsLoc; - TypeLoc CastTy; + TypeExpr *const CastTy; protected: - ExplicitCastExpr(ExprKind kind, Expr *sub, SourceLoc AsLoc, TypeLoc castTy) - : Expr(kind, /*Implicit=*/false), SubExpr(sub), AsLoc(AsLoc), CastTy(castTy) - {} + ExplicitCastExpr(ExprKind kind, Expr *sub, SourceLoc AsLoc, TypeExpr *castTy) + : Expr(kind, /*Implicit=*/false), SubExpr(sub), AsLoc(AsLoc), + CastTy(castTy) {} public: Expr *getSubExpr() const { return SubExpr; } - - /// Get the type syntactically spelled in the cast. For some forms of checked - /// cast this is different from the result type of the expression. - TypeLoc &getCastTypeLoc() { return CastTy; } /// Get the type syntactically spelled in the cast. For some forms of checked /// cast this is different from the result type of the expression. - TypeLoc getCastTypeLoc() const { return CastTy; } + Type getCastType() const { return CastTy->getInstanceType(); } + void setCastType(Type type); + + TypeRepr *getCastTypeRepr() const { return CastTy->getTypeRepr(); } void setSubExpr(Expr *E) { SubExpr = E; } @@ -4623,7 +4627,7 @@ class ExplicitCastExpr : public Expr { } SourceRange getSourceRange() const { - SourceRange castTyRange = CastTy.getSourceRange(); + const SourceRange castTyRange = CastTy->getSourceRange(); if (castTyRange.isInvalid()) return SubExpr->getSourceRange(); @@ -4648,14 +4652,13 @@ StringRef getCheckedCastKindName(CheckedCastKind kind); /// Abstract base class for checked casts 'as' and 'is'. These represent /// casts that can dynamically fail. class CheckedCastExpr : public ExplicitCastExpr { -public: - CheckedCastExpr(ExprKind kind, - Expr *sub, SourceLoc asLoc, TypeLoc castTy) - : ExplicitCastExpr(kind, sub, asLoc, castTy) - { +protected: + CheckedCastExpr(ExprKind kind, Expr *sub, SourceLoc asLoc, TypeExpr *castTy) + : ExplicitCastExpr(kind, sub, asLoc, castTy) { Bits.CheckedCastExpr.CastKind = unsigned(CheckedCastKind::Unresolved); } - + +public: /// Return the semantic kind of cast performed. CheckedCastKind getCastKind() const { return CheckedCastKind(Bits.CheckedCastExpr.CastKind); @@ -4679,22 +4682,20 @@ class CheckedCastExpr : public ExplicitCastExpr { /// from a value of some type to some specified subtype and fails dynamically /// if the value does not have that type. /// Spelled 'a as! T' and produces a value of type 'T'. -class ForcedCheckedCastExpr : public CheckedCastExpr { +class ForcedCheckedCastExpr final : public CheckedCastExpr { SourceLoc ExclaimLoc; -public: ForcedCheckedCastExpr(Expr *sub, SourceLoc asLoc, SourceLoc exclaimLoc, - TypeLoc type) - : CheckedCastExpr(ExprKind::ForcedCheckedCast, - sub, asLoc, type), - ExclaimLoc(exclaimLoc) - { - } + TypeExpr *type) + : CheckedCastExpr(ExprKind::ForcedCheckedCast, sub, asLoc, type), + ExclaimLoc(exclaimLoc) {} - ForcedCheckedCastExpr(SourceLoc asLoc, SourceLoc exclaimLoc, TypeLoc type) - : ForcedCheckedCastExpr(nullptr, asLoc, exclaimLoc, type) - { - } +public: + static ForcedCheckedCastExpr *create(ASTContext &ctx, SourceLoc asLoc, + SourceLoc exclaimLoc, TypeRepr *tyRepr); + + static ForcedCheckedCastExpr *createImplicit(ASTContext &ctx, Expr *sub, + Type castTy); /// Retrieve the location of the '!' that follows 'as'. SourceLoc getExclaimLoc() const { return ExclaimLoc; } @@ -4708,21 +4709,24 @@ class ForcedCheckedCastExpr : public CheckedCastExpr { /// from a type to some subtype and produces an Optional value, which will be /// .Some(x) if the cast succeeds, or .None if the cast fails. /// Spelled 'a as? T' and produces a value of type 'T?'. -class ConditionalCheckedCastExpr : public CheckedCastExpr { +class ConditionalCheckedCastExpr final : public CheckedCastExpr { SourceLoc QuestionLoc; -public: ConditionalCheckedCastExpr(Expr *sub, SourceLoc asLoc, SourceLoc questionLoc, - TypeLoc type) - : CheckedCastExpr(ExprKind::ConditionalCheckedCast, - sub, asLoc, type), - QuestionLoc(questionLoc) - { } - - ConditionalCheckedCastExpr(SourceLoc asLoc, SourceLoc questionLoc, - TypeLoc type) - : ConditionalCheckedCastExpr(nullptr, asLoc, questionLoc, type) - {} + TypeExpr *type) + : CheckedCastExpr(ExprKind::ConditionalCheckedCast, sub, asLoc, type), + QuestionLoc(questionLoc) {} + +public: + static ConditionalCheckedCastExpr *create(ASTContext &ctx, SourceLoc asLoc, + SourceLoc questionLoc, + TypeRepr *tyRepr); + + static ConditionalCheckedCastExpr *createImplicit(ASTContext &ctx, Expr *sub, + Type castTy); + + static ConditionalCheckedCastExpr * + createImplicit(ASTContext &ctx, Expr *sub, TypeRepr *tyRepr, Type castTy); /// Retrieve the location of the '?' that follows 'as'. SourceLoc getQuestionLoc() const { return QuestionLoc; } @@ -4737,16 +4741,13 @@ class ConditionalCheckedCastExpr : public CheckedCastExpr { /// of the type and 'a as T' would succeed, false otherwise. /// /// FIXME: We should support type queries with a runtime metatype value too. -class IsExpr : public CheckedCastExpr { +class IsExpr final : public CheckedCastExpr { + IsExpr(Expr *sub, SourceLoc isLoc, TypeExpr *type) + : CheckedCastExpr(ExprKind::Is, sub, isLoc, type) {} + public: - IsExpr(Expr *sub, SourceLoc isLoc, TypeLoc type) - : CheckedCastExpr(ExprKind::Is, sub, isLoc, type) - {} - - IsExpr(SourceLoc isLoc, TypeLoc type) - : IsExpr(nullptr, isLoc, type) - {} - + static IsExpr *create(ASTContext &ctx, SourceLoc isLoc, TypeRepr *tyRepr); + static bool classof(const Expr *E) { return E->getKind() == ExprKind::Is; } @@ -4755,35 +4756,29 @@ class IsExpr : public CheckedCastExpr { /// Represents an explicit coercion from a value to a specific type. /// /// Spelled 'a as T' and produces a value of type 'T'. -class CoerceExpr : public ExplicitCastExpr { +class CoerceExpr final : public ExplicitCastExpr { /// Since there is already `asLoc` location, /// we use it to store `start` of the initializer /// call source range to save some storage. SourceLoc InitRangeEnd; -public: - CoerceExpr(Expr *sub, SourceLoc asLoc, TypeLoc type) - : ExplicitCastExpr(ExprKind::Coerce, sub, asLoc, type) - { } + CoerceExpr(Expr *sub, SourceLoc asLoc, TypeExpr *type) + : ExplicitCastExpr(ExprKind::Coerce, sub, asLoc, type) {} - CoerceExpr(SourceLoc asLoc, TypeLoc type) - : CoerceExpr(nullptr, asLoc, type) - { } - -private: - CoerceExpr(SourceRange initRange, Expr *literal, TypeLoc type) - : ExplicitCastExpr(ExprKind::Coerce, literal, initRange.Start, - type), InitRangeEnd(initRange.End) - { setImplicit(); } + CoerceExpr(SourceRange initRange, Expr *literal, TypeExpr *type) + : ExplicitCastExpr(ExprKind::Coerce, literal, initRange.Start, type), + InitRangeEnd(initRange.End) {} public: + static CoerceExpr *create(ASTContext &ctx, SourceLoc asLoc, TypeRepr *tyRepr); + + static CoerceExpr *createImplicit(ASTContext &ctx, Expr *sub, Type castTy); + /// Create an implicit coercion expression for literal initialization /// preserving original source information, this way original call /// could be recreated if needed. static CoerceExpr *forLiteralInit(ASTContext &ctx, Expr *literal, - SourceRange range, TypeLoc literalType) { - return new (ctx) CoerceExpr(range, literal, literalType); - } + SourceRange range, TypeRepr *literalTyRepr); bool isLiteralInit() const { return InitRangeEnd.isValid(); } diff --git a/include/swift/AST/FileSystem.h b/include/swift/AST/FileSystem.h index 90d693a4fee9e..15641164c3e08 100644 --- a/include/swift/AST/FileSystem.h +++ b/include/swift/AST/FileSystem.h @@ -15,6 +15,7 @@ #include "swift/Basic/FileSystem.h" #include "swift/AST/DiagnosticEngine.h" +#include "swift/AST/DiagnosticsCommon.h" namespace swift { diff --git a/include/swift/AST/FileUnit.h b/include/swift/AST/FileUnit.h index bd251279bdf3f..e15a56560fcf6 100644 --- a/include/swift/AST/FileUnit.h +++ b/include/swift/AST/FileUnit.h @@ -107,8 +107,8 @@ class FileUnit : public DeclContext { /// Find all SPI names imported from \p importedModule by this module, /// collecting the identifiers in \p spiGroups. virtual void lookupImportedSPIGroups( - const ModuleDecl *importedModule, - SmallVectorImpl &spiGroups) const {}; + const ModuleDecl *importedModule, + SmallSetVector &spiGroups) const {}; protected: /// Look up an operator declaration. Do not call directly, use @@ -384,6 +384,9 @@ class LoadedFile : public FileUnit { virtual bool isSystemModule() const { return false; } + /// Checks whether an error was encountered while loading the file. + virtual bool hadLoadError() const { return false; } + /// Retrieve the set of generic signatures stored within this module. /// /// \returns \c true if this module file supports retrieving all of the diff --git a/include/swift/AST/FineGrainedDependencies.h b/include/swift/AST/FineGrainedDependencies.h index f76a0f5305484..381b4443c0cb3 100644 --- a/include/swift/AST/FineGrainedDependencies.h +++ b/include/swift/AST/FineGrainedDependencies.h @@ -1,4 +1,4 @@ -//===----- FineGrainedependencies.h -----------------------------*- C++ -*-===// +//===----- FineGrainedDependencies.h ----------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // @@ -632,6 +632,11 @@ class DepGraphNode { const DependencyKey &getKey() const { return key; } + /// Only used when the driver is reading a SourceFileDepGraphNode. + void setKey(const DependencyKey &key) { + this->key = key; + } + const Optional getFingerprint() const { if (fingerprint) { return StringRef(fingerprint.getValue()); @@ -684,7 +689,7 @@ class SourceFileDepGraphNode : public DepGraphNode { /// True iff a Decl exists for this node. /// If a provides and a depends in the existing system both have the same key, /// only one SourceFileDepGraphNode is emitted. - bool isProvides; + bool isProvides = false; friend ::llvm::yaml::MappingContextTraits; @@ -692,7 +697,7 @@ class SourceFileDepGraphNode : public DepGraphNode { public: /// When the driver imports a node create an uninitialized instance for /// deserializing. - SourceFileDepGraphNode() : DepGraphNode(), sequenceNumber(~0) {} + SourceFileDepGraphNode() : DepGraphNode() {} /// Used by the frontend to build nodes. SourceFileDepGraphNode(DependencyKey key, Optional fingerprint, @@ -736,6 +741,9 @@ class SourceFileDepGraphNode : public DepGraphNode { : "somewhere else"); } + SWIFT_DEBUG_DUMP; + void dump(llvm::raw_ostream &os) const; + bool verify() const { DepGraphNode::verify(); assert(getIsProvides() || isDepends()); @@ -872,7 +880,6 @@ class SourceFileDepGraph { void emitDotFile(StringRef outputPath, DiagnosticEngine &diags); -private: void addNode(SourceFileDepGraphNode *n) { n->setSequenceNumber(allNodes.size()); allNodes.push_back(n); diff --git a/include/swift/AST/FineGrainedDependencyFormat.h b/include/swift/AST/FineGrainedDependencyFormat.h new file mode 100644 index 0000000000000..a4d35695ceebb --- /dev/null +++ b/include/swift/AST/FineGrainedDependencyFormat.h @@ -0,0 +1,133 @@ +//===---- FineGrainedDependencyFormat.h - swiftdeps format ---*- C++ -*-======// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_AST_FINEGRAINEDDEPENDENCYFORMAT_H +#define SWIFT_AST_FINEGRAINEDDEPENDENCYFORMAT_H + +#include "llvm/Bitcode/RecordLayout.h" +#include "llvm/Bitstream/BitCodes.h" + +namespace llvm { +class MemoryBuffer; +} + +namespace swift { + +class DiagnosticEngine; + +namespace fine_grained_dependencies { + +class SourceFileDepGraph; + +using llvm::BCFixed; +using llvm::BCVBR; +using llvm::BCBlob; +using llvm::BCRecordLayout; + +/// Every .swiftdeps file begins with these 4 bytes, for easy identification when +/// debugging. +const unsigned char FINE_GRAINED_DEPDENENCY_FORMAT_SIGNATURE[] = {'D', 'E', 'P', 'S'}; + +const unsigned FINE_GRAINED_DEPENDENCY_FORMAT_VERSION_MAJOR = 1; + +/// Increment this on every change. +const unsigned FINE_GRAINED_DEPENDENCY_FORMAT_VERSION_MINOR = 0; + +using IdentifierIDField = BCVBR<13>; + +using NodeKindField = BCFixed<3>; +using DeclAspectField = BCFixed<1>; + +const unsigned RECORD_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID; + +/// The swiftdeps file format consists of a METADATA record, followed by zero or more +/// IDENTIFIER_NODE records. +/// +/// Then, there is one SOURCE_FILE_DEP_GRAPH_NODE for each serialized +/// SourceFileDepGraphNode. These are followed by FINGERPRINT_NODE and +/// DEPENDS_ON_DEFINITION_NODE, if the node has a fingerprint and depends-on +/// definitions, respectively. +namespace record_block { + enum { + METADATA = 1, + SOURCE_FILE_DEP_GRAPH_NODE, + FINGERPRINT_NODE, + DEPENDS_ON_DEFINITION_NODE, + IDENTIFIER_NODE, + }; + + // Always the first record in the file. + using MetadataLayout = BCRecordLayout< + METADATA, // ID + BCFixed<16>, // Dependency graph format major version + BCFixed<16>, // Dependency graph format minor version + BCBlob // Compiler version string + >; + + // After the metadata record, we have zero or more identifier records, + // for each unique string that is referenced from a SourceFileDepGraphNode. + // + // Identifiers are referenced by their sequence number, starting from 1. + // The identifier value 0 is special; it always represents the empty string. + // There is no IDENTIFIER_NODE serialized that corresponds to it, instead + // the first IDENTIFIER_NODE always has a sequence number of 1. + using IdentifierNodeLayout = BCRecordLayout< + IDENTIFIER_NODE, + BCBlob + >; + + using SourceFileDepGraphNodeLayout = BCRecordLayout< + SOURCE_FILE_DEP_GRAPH_NODE, // ID + // The next four fields correspond to the fields of the DependencyKey + // structure. + NodeKindField, // DependencyKey::kind + DeclAspectField, // DependencyKey::aspect + IdentifierIDField, // DependencyKey::context + IdentifierIDField, // DependencyKey::name + BCFixed<1> // Is this a "provides" node? + >; + + // Follows DEPENDS_ON_DEFINITION_NODE when the SourceFileDepGraphNode has a + // fingerprint set. + using FingerprintNodeLayout = BCRecordLayout< + FINGERPRINT_NODE, + BCBlob + >; + + // Follows SOURCE_FILE_DEP_GRAPH_NODE and FINGERPRINT_NODE when the + // SourceFileDepGraphNode has one or more depends-on entries. + using DependsOnDefNodeLayout = BCRecordLayout< + DEPENDS_ON_DEFINITION_NODE, + BCVBR<16> // The sequence number (starting from 0) of the referenced + // SOURCE_FILE_DEP_GRAPH_NODE + >; +} + +/// Tries to read the dependency graph from the given buffer. +/// Returns true if there was an error. +bool readFineGrainedDependencyGraph(llvm::MemoryBuffer &buffer, + SourceFileDepGraph &g); + +/// Tries to read the dependency graph from the given path name. +/// Returns true if there was an error. +bool readFineGrainedDependencyGraph(llvm::StringRef path, + SourceFileDepGraph &g); + +/// Tries to write the dependency graph to the given path name. +/// Returns true if there was an error. +bool writeFineGrainedDependencyGraph(DiagnosticEngine &diags, llvm::StringRef path, + const SourceFileDepGraph &g); + +} // namespace fine_grained_dependencies +} // namespace swift + +#endif diff --git a/include/swift/AST/GenericParamKey.h b/include/swift/AST/GenericParamKey.h index 081c47a8aa571..f8590f8c4e124 100644 --- a/include/swift/AST/GenericParamKey.h +++ b/include/swift/AST/GenericParamKey.h @@ -14,7 +14,6 @@ #define SWIFT_AST_GENERICPARAMKEY_H #include "llvm/ADT/DenseMapInfo.h" -#include "llvm/ADT/ArrayRef.h" #include "swift/AST/Type.h" namespace swift { diff --git a/include/swift/AST/GenericSignature.h b/include/swift/AST/GenericSignature.h index 4d347fae5b9d8..271e07899698f 100644 --- a/include/swift/AST/GenericSignature.h +++ b/include/swift/AST/GenericSignature.h @@ -329,12 +329,12 @@ class alignas(1 << TypeAlignInBits) GenericSignatureImpl final /// Determine whether the given dependent type is equal to a concrete type. bool isConcreteType(Type type) const; - /// Return the concrete type that the given dependent type is constrained to, + /// Return the concrete type that the given type parameter is constrained to, /// or the null Type if it is not the subject of a concrete same-type /// constraint. Type getConcreteType(Type type) const; - /// Return the layout constraint that the given dependent type is constrained + /// Return the layout constraint that the given type parameter is constrained /// to, or the null LayoutConstraint if it is not the subject of layout /// constraint. LayoutConstraint getLayoutConstraint(Type type) const; diff --git a/include/swift/AST/GenericSignatureBuilder.h b/include/swift/AST/GenericSignatureBuilder.h index 21b9c60d65a04..abb790e466a14 100644 --- a/include/swift/AST/GenericSignatureBuilder.h +++ b/include/swift/AST/GenericSignatureBuilder.h @@ -30,7 +30,6 @@ #include "swift/AST/TypeRepr.h" #include "swift/Basic/Debug.h" #include "swift/Basic/LLVM.h" -#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/ilist.h" #include "llvm/ADT/PointerUnion.h" diff --git a/include/swift/AST/IRGenOptions.h b/include/swift/AST/IRGenOptions.h index 1a90d3572ba82..279fdcefb3c4e 100644 --- a/include/swift/AST/IRGenOptions.h +++ b/include/swift/AST/IRGenOptions.h @@ -190,9 +190,6 @@ class IRGenOptions { /// Whether we should run LLVM SLP vectorizer. unsigned DisableLLVMSLPVectorizer : 1; - /// Disable frame pointer elimination? - unsigned DisableFPElim : 1; - /// Special codegen for playgrounds. unsigned Playground : 1; @@ -319,7 +316,7 @@ class IRGenOptions { DisableClangModuleSkeletonCUs(false), UseJIT(false), DisableLLVMOptzns(false), DisableSwiftSpecificLLVMOptzns(false), DisableLLVMSLPVectorizer(false), - DisableFPElim(true), Playground(false), EmitStackPromotionChecks(false), + Playground(false), EmitStackPromotionChecks(false), FunctionSections(false), PrintInlineTree(false), EmbedMode(IRGenEmbedMode::None), HasValueNamesSetting(false), ValueNames(false), EnableReflectionMetadata(true), EnableReflectionNames(true), diff --git a/include/swift/AST/IRGenRequests.h b/include/swift/AST/IRGenRequests.h index dd19afa4bedb6..3cd8212176aee 100644 --- a/include/swift/AST/IRGenRequests.h +++ b/include/swift/AST/IRGenRequests.h @@ -200,7 +200,7 @@ class IRGenSourceFileRequest public: // Incremental dependencies. evaluator::DependencySource - readDependencySource(const evaluator::DependencyCollector &) const; + readDependencySource(const evaluator::DependencyRecorder &) const; }; class IRGenWholeModuleRequest diff --git a/include/swift/AST/KnownDecls.def b/include/swift/AST/KnownDecls.def index 32ce519b12c57..15a5081285d1d 100644 --- a/include/swift/AST/KnownDecls.def +++ b/include/swift/AST/KnownDecls.def @@ -44,6 +44,8 @@ FUNC_DECL(AllocateUninitializedArray, "_allocateUninitializedArray") FUNC_DECL(DeallocateUninitializedArray, "_deallocateUninitializedArray") +FUNC_DECL(FinalizeUninitializedArray, + "_finalizeUninitializedArray") FUNC_DECL(ForceBridgeFromObjectiveC, "_forceBridgeFromObjectiveC") diff --git a/include/swift/AST/KnownIdentifiers.def b/include/swift/AST/KnownIdentifiers.def index 7dd491d870d22..24c9f9c3d979c 100644 --- a/include/swift/AST/KnownIdentifiers.def +++ b/include/swift/AST/KnownIdentifiers.def @@ -223,6 +223,7 @@ IDENTIFIER(move) IDENTIFIER(pullback) IDENTIFIER(TangentVector) IDENTIFIER(zero) +IDENTIFIER(zeroTangentVectorInitializer) #undef IDENTIFIER #undef IDENTIFIER_ diff --git a/include/swift/AST/LazyResolver.h b/include/swift/AST/LazyResolver.h index eb468f7cfe855..ee6e64ff25ac8 100644 --- a/include/swift/AST/LazyResolver.h +++ b/include/swift/AST/LazyResolver.h @@ -18,7 +18,6 @@ #define SWIFT_AST_LAZYRESOLVER_H #include "swift/AST/ProtocolConformanceRef.h" -#include "swift/AST/TypeLoc.h" #include "llvm/ADT/PointerEmbeddedInt.h" namespace swift { diff --git a/include/swift/AST/LinkLibrary.h b/include/swift/AST/LinkLibrary.h index 44a5d9c7e3ede..c40cc6f024348 100644 --- a/include/swift/AST/LinkLibrary.h +++ b/include/swift/AST/LinkLibrary.h @@ -14,7 +14,7 @@ #define SWIFT_AST_LINKLIBRARY_H #include "swift/Basic/LLVM.h" -#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringRef.h" #include namespace swift { diff --git a/include/swift/AST/Module.h b/include/swift/AST/Module.h index c5a70a6e66773..3817283cfe3f0 100644 --- a/include/swift/AST/Module.h +++ b/include/swift/AST/Module.h @@ -22,22 +22,18 @@ #include "swift/AST/Identifier.h" #include "swift/AST/LookupKinds.h" #include "swift/AST/RawComment.h" -#include "swift/AST/ReferencedNameTracker.h" #include "swift/AST/Type.h" #include "swift/Basic/Compiler.h" #include "swift/Basic/OptionSet.h" #include "swift/Basic/STLExtras.h" #include "swift/Basic/SourceLoc.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/SetVector.h" -#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" -#include "llvm/ADT/TinyPtrVector.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MD5.h" +#include namespace clang { class Module; @@ -69,7 +65,6 @@ namespace swift { class ProtocolConformance; class ProtocolDecl; struct PrintOptions; - class ReferencedNameTracker; class Token; class TupleType; class Type; @@ -365,6 +360,7 @@ class ModuleDecl : public DeclContext, public TypeDecl { ArrayRef getImplicitImports() const; ArrayRef getFiles() { + assert(!Files.empty() || failedToLoad()); return Files; } ArrayRef getFiles() const { @@ -373,7 +369,6 @@ class ModuleDecl : public DeclContext, public TypeDecl { bool isClangModule() const; void addFile(FileUnit &newFile); - void removeFile(FileUnit &existingFile); /// Creates a map from \c #filePath strings to corresponding \c #file /// strings, diagnosing any conflicts. @@ -396,6 +391,11 @@ class ModuleDecl : public DeclContext, public TypeDecl { /// Add a file declaring a cross-import overlay. void addCrossImportOverlayFile(StringRef file); + /// Collect cross-import overlay names from a given YAML file path. + static llvm::SmallSetVector + collectCrossImportOverlay(ASTContext &ctx, StringRef file, + StringRef moduleName, StringRef& bystandingModule); + /// If this method returns \c false, the module does not declare any /// cross-import overlays. /// @@ -553,6 +553,10 @@ class ModuleDecl : public DeclContext, public TypeDecl { return Bits.ModuleDecl.IsMainModule; } + /// For the main module, retrieves the list of primary source files being + /// compiled, that is, the files we're generating code for. + ArrayRef getPrimarySourceFiles() const; + /// Retrieve the top-level module. If this module is already top-level, this /// returns itself. If this is a submodule such as \c Foo.Bar.Baz, this /// returns the module \c Foo. @@ -592,21 +596,6 @@ class ModuleDecl : public DeclContext, public TypeDecl { /// FIXME: Remove the integrated REPL. void clearLookupCache(); - /// @{ - - /// Look up the given operator in this module. - /// - /// If the operator is not found, or if there is an ambiguity, returns null. - InfixOperatorDecl *lookupInfixOperator(Identifier name, - SourceLoc diagLoc = {}); - PrefixOperatorDecl *lookupPrefixOperator(Identifier name, - SourceLoc diagLoc = {}); - PostfixOperatorDecl *lookupPostfixOperator(Identifier name, - SourceLoc diagLoc = {}); - PrecedenceGroupDecl *lookupPrecedenceGroup(Identifier name, - SourceLoc diagLoc = {}); - /// @} - /// Finds all class members defined in this module. /// /// This does a simple local lookup, not recursively looking through imports. @@ -663,8 +652,9 @@ class ModuleDecl : public DeclContext, public TypeDecl { /// Find all SPI names imported from \p importedModule by this module, /// collecting the identifiers in \p spiGroups. - void lookupImportedSPIGroups(const ModuleDecl *importedModule, - SmallVectorImpl &spiGroups) const; + void lookupImportedSPIGroups( + const ModuleDecl *importedModule, + llvm::SmallSetVector &spiGroups) const; /// \sa getImportedModules enum class ImportFilterKind { diff --git a/include/swift/AST/ModuleDependencies.h b/include/swift/AST/ModuleDependencies.h index e169eff011f79..47ff92fa8f3e4 100644 --- a/include/swift/AST/ModuleDependencies.h +++ b/include/swift/AST/ModuleDependencies.h @@ -20,7 +20,6 @@ #include "swift/Basic/LLVM.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringSet.h" #include @@ -30,6 +29,8 @@ namespace swift { class ClangModuleDependenciesCacheImpl; class SourceFile; +class ASTContext; +class Identifier; /// Which kind of module dependencies we are looking for. enum class ModuleDependenciesKind : int8_t { @@ -247,6 +248,11 @@ class ModuleDependencies { /// Add (Clang) module on which the bridging header depends. void addBridgingModuleDependency(StringRef module, llvm::StringSet<> &alreadyAddedModules); + + /// Collect a map from a secondary module name to a list of cross-import + /// overlays, when this current module serves as the primary module. + llvm::StringMap> + collectCrossImportOverlayNames(ASTContext &ctx, StringRef moduleName); }; using ModuleDependencyID = std::pair; diff --git a/include/swift/AST/ModuleLoader.h b/include/swift/AST/ModuleLoader.h index bec885cb58739..6abeebcb8b8ba 100644 --- a/include/swift/AST/ModuleLoader.h +++ b/include/swift/AST/ModuleLoader.h @@ -22,8 +22,6 @@ #include "swift/Basic/Located.h" #include "swift/Basic/SourceLoc.h" #include "llvm/ADT/SetVector.h" -#include "llvm/ADT/SmallSet.h" -#include "llvm/ADT/StringSet.h" #include "llvm/ADT/TinyPtrVector.h" #include "swift/AST/ModuleDependencies.h" diff --git a/include/swift/AST/NameLookup.h b/include/swift/AST/NameLookup.h index 911a259dd0135..9d6a68516c494 100644 --- a/include/swift/AST/NameLookup.h +++ b/include/swift/AST/NameLookup.h @@ -17,7 +17,6 @@ #ifndef SWIFT_AST_NAME_LOOKUP_H #define SWIFT_AST_NAME_LOOKUP_H -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "swift/AST/ASTVisitor.h" #include "swift/AST/Identifier.h" @@ -455,6 +454,26 @@ bool removeOverriddenDecls(SmallVectorImpl &decls); bool removeShadowedDecls(SmallVectorImpl &decls, const DeclContext *dc); +/// Remove any operators in the given set that are shadowed by +/// other operators in that set. +/// +/// \param decls The set of operators being considered. +/// \param dc The DeclContext from which the lookup was performed. +/// +/// \returns true if any shadowed declarations were removed. +bool removeShadowedDecls(TinyPtrVector &decls, + const DeclContext *dc); + +/// Remove any precedence groups in the given set that are shadowed by +/// other precedence groups in that set. +/// +/// \param decls The set of precedence groups being considered. +/// \param dc The DeclContext from which the lookup was performed. +/// +/// \returns true if any shadowed declarations were removed. +bool removeShadowedDecls(TinyPtrVector &decls, + const DeclContext *dc); + /// Finds decls visible in the given context and feeds them to the given /// VisibleDeclConsumer. If the current DeclContext is nested in a function, /// the SourceLoc is used to determine which declarations in that function diff --git a/include/swift/AST/NameLookupRequests.h b/include/swift/AST/NameLookupRequests.h index df8c0dea04179..be6be839b0a81 100644 --- a/include/swift/AST/NameLookupRequests.h +++ b/include/swift/AST/NameLookupRequests.h @@ -189,7 +189,7 @@ class InheritedProtocolsRequest public: // Incremental dependencies evaluator::DependencySource - readDependencySource(const evaluator::DependencyCollector &e) const; + readDependencySource(const evaluator::DependencyRecorder &e) const; void writeDependencySink(evaluator::DependencyCollector &tracker, ArrayRef result) const; }; @@ -330,7 +330,7 @@ class GetDestructorRequest public: // Incremental dependencies. evaluator::DependencySource - readDependencySource(const evaluator::DependencyCollector &) const; + readDependencySource(const evaluator::DependencyRecorder &) const; }; class GenericParamListRequest : @@ -434,7 +434,7 @@ class UnqualifiedLookupRequest public: // Incremental dependencies evaluator::DependencySource - readDependencySource(const evaluator::DependencyCollector &) const; + readDependencySource(const evaluator::DependencyRecorder &) const; void writeDependencySink(evaluator::DependencyCollector &tracker, LookupResult res) const; }; @@ -447,7 +447,7 @@ class LookupInModuleRequest QualifiedLookupResult( const DeclContext *, DeclName, NLKind, namelookup::ResolutionKind, const DeclContext *), - RequestFlags::Uncached> { + RequestFlags::Uncached | RequestFlags::DependencySink> { public: using SimpleRequest::SimpleRequest; @@ -459,6 +459,11 @@ class LookupInModuleRequest evaluate(Evaluator &evaluator, const DeclContext *moduleOrFile, DeclName name, NLKind lookupKind, namelookup::ResolutionKind resolutionKind, const DeclContext *moduleScopeContext) const; + +public: + // Incremental dependencies + void writeDependencySink(evaluator::DependencyCollector &tracker, + QualifiedLookupResult l) const; }; /// Perform \c AnyObject lookup for a given member. @@ -506,7 +511,7 @@ class ModuleQualifiedLookupRequest public: // Incremental dependencies evaluator::DependencySource - readDependencySource(const evaluator::DependencyCollector &) const; + readDependencySource(const evaluator::DependencyRecorder &) const; void writeDependencySink(evaluator::DependencyCollector &tracker, QualifiedLookupResult lookupResult) const; }; @@ -533,7 +538,7 @@ class QualifiedLookupRequest public: // Incremental dependencies. evaluator::DependencySource - readDependencySource(const evaluator::DependencyCollector &) const; + readDependencySource(const evaluator::DependencyRecorder &) const; }; /// The input type for a direct lookup request. @@ -594,14 +599,10 @@ class OperatorLookupDescriptor final { using Storage = llvm::PointerUnion; Storage fileOrModule; Identifier name; - bool isCascading; - SourceLoc diagLoc; private: - OperatorLookupDescriptor(Storage fileOrModule, Identifier name, - bool isCascading, SourceLoc diagLoc) - : fileOrModule(fileOrModule), name(name), isCascading(isCascading), - diagLoc(diagLoc) {} + OperatorLookupDescriptor(Storage fileOrModule, Identifier name) + : fileOrModule(fileOrModule), name(name) {} public: /// Retrieves the files to perform lookup in. @@ -613,14 +614,20 @@ class OperatorLookupDescriptor final { return fileOrModule.dyn_cast(); } + /// Retrieve the file or module for the lookup, as a DeclContext. + DeclContext *getDC() const { + if (auto *module = getModule()) + return module; + return fileOrModule.get(); + } + friend llvm::hash_code hash_value(const OperatorLookupDescriptor &desc) { - return llvm::hash_combine(desc.fileOrModule, desc.name, desc.isCascading); + return llvm::hash_combine(desc.fileOrModule, desc.name); } friend bool operator==(const OperatorLookupDescriptor &lhs, const OperatorLookupDescriptor &rhs) { - return lhs.fileOrModule == rhs.fileOrModule && lhs.name == rhs.name && - lhs.isCascading == rhs.isCascading; + return lhs.fileOrModule == rhs.fileOrModule && lhs.name == rhs.name; } friend bool operator!=(const OperatorLookupDescriptor &lhs, @@ -628,16 +635,15 @@ class OperatorLookupDescriptor final { return !(lhs == rhs); } - static OperatorLookupDescriptor forFile(FileUnit *file, Identifier name, - bool isCascading, SourceLoc diagLoc) { - return OperatorLookupDescriptor(file, name, isCascading, diagLoc); + static OperatorLookupDescriptor forFile(FileUnit *file, Identifier name) { + return OperatorLookupDescriptor(file, name); } - static OperatorLookupDescriptor forModule(ModuleDecl *mod, Identifier name, - bool isCascading, - SourceLoc diagLoc) { - return OperatorLookupDescriptor(mod, name, isCascading, diagLoc); + static OperatorLookupDescriptor forModule(ModuleDecl *mod, Identifier name) { + return OperatorLookupDescriptor(mod, name); } + + static OperatorLookupDescriptor forDC(const DeclContext *DC, Identifier name); }; void simple_display(llvm::raw_ostream &out, @@ -645,34 +651,6 @@ void simple_display(llvm::raw_ostream &out, SourceLoc extractNearestSourceLoc(const OperatorLookupDescriptor &desc); -template -class LookupOperatorRequest - : public SimpleRequest, - OperatorType *(OperatorLookupDescriptor), - RequestFlags::Cached> { - using SimpleRequest, - OperatorType *(OperatorLookupDescriptor), - RequestFlags::Cached>::SimpleRequest; - -private: - friend SimpleRequest, - OperatorType *(OperatorLookupDescriptor), - RequestFlags::Cached>; - - // Evaluation. - OperatorType *evaluate(Evaluator &evaluator, - OperatorLookupDescriptor desc) const; - -public: - // Cached. - bool isCached() const { return true; } -}; - -using LookupPrefixOperatorRequest = LookupOperatorRequest; -using LookupInfixOperatorRequest = LookupOperatorRequest; -using LookupPostfixOperatorRequest = LookupOperatorRequest; -using LookupPrecedenceGroupRequest = LookupOperatorRequest; - /// Looks up an operator in a given file or module without looking through /// imports. class DirectOperatorLookupRequest @@ -770,6 +748,84 @@ class LookupConformanceInModuleRequest ProtocolConformanceRef result) const; }; +/// Look up an 'infix operator' decl by name. +class LookupInfixOperatorRequest + : public SimpleRequest( + OperatorLookupDescriptor), + RequestFlags::Cached> { +public: + using SimpleRequest::SimpleRequest; + +private: + friend SimpleRequest; + + TinyPtrVector + evaluate(Evaluator &evaluator, OperatorLookupDescriptor desc) const; + +public: + // Cached. + bool isCached() const { return true; } +}; + +/// Look up an 'prefix operator' decl by name. +class LookupPrefixOperatorRequest + : public SimpleRequest { +public: + using SimpleRequest::SimpleRequest; + +private: + friend SimpleRequest; + + PrefixOperatorDecl *evaluate(Evaluator &evaluator, + OperatorLookupDescriptor desc) const; + +public: + // Cached. + bool isCached() const { return true; } +}; + +/// Look up an 'postfix operator' decl by name. +class LookupPostfixOperatorRequest + : public SimpleRequest { +public: + using SimpleRequest::SimpleRequest; + +private: + friend SimpleRequest; + + PostfixOperatorDecl *evaluate(Evaluator &evaluator, + OperatorLookupDescriptor desc) const; + +public: + // Cached. + bool isCached() const { return true; } +}; + +/// Look up a precedencegroup decl by name. +class LookupPrecedenceGroupRequest + : public SimpleRequest( + OperatorLookupDescriptor), + RequestFlags::Cached> { +public: + using SimpleRequest::SimpleRequest; + +private: + friend SimpleRequest; + + TinyPtrVector + evaluate(Evaluator &evaluator, OperatorLookupDescriptor descriptor) const; + +public: + // Cached. + bool isCached() const { return true; } +}; + #define SWIFT_TYPEID_ZONE NameLookup #define SWIFT_TYPEID_HEADER "swift/AST/NameLookupTypeIDZone.def" #include "swift/Basic/DefineTypeIDZone.h" diff --git a/include/swift/AST/NameLookupTypeIDZone.def b/include/swift/AST/NameLookupTypeIDZone.def index de346c54f8806..b67a2bbabe078 100644 --- a/include/swift/AST/NameLookupTypeIDZone.def +++ b/include/swift/AST/NameLookupTypeIDZone.def @@ -89,11 +89,11 @@ SWIFT_REQUEST(NameLookup, LookupPrefixOperatorRequest, PrefixOperatorDecl *(OperatorLookupDescriptor), Cached, NoLocationInfo) SWIFT_REQUEST(NameLookup, LookupInfixOperatorRequest, - InfixOperatorDecl *(OperatorLookupDescriptor), + TinyPtrVector(OperatorLookupDescriptor), Cached, NoLocationInfo) SWIFT_REQUEST(NameLookup, LookupPostfixOperatorRequest, PostfixOperatorDecl *(OperatorLookupDescriptor), Cached, NoLocationInfo) SWIFT_REQUEST(NameLookup, LookupPrecedenceGroupRequest, - PrecedenceGroupDecl *(OperatorLookupDescriptor), + TinyPtrVector(OperatorLookupDescriptor), Cached, NoLocationInfo) diff --git a/include/swift/AST/OperatorNameLookup.h b/include/swift/AST/OperatorNameLookup.h new file mode 100644 index 0000000000000..6cea9e69e7d26 --- /dev/null +++ b/include/swift/AST/OperatorNameLookup.h @@ -0,0 +1,127 @@ +//===--- OperatorNameLookup.h - Operator and Precedence Lookup --*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2020 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file defines interfaces for looking up operator and precedence group +// declarations. +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_AST_OPERATOR_NAME_LOOKUP_H +#define SWIFT_AST_OPERATOR_NAME_LOOKUP_H + +#include "swift/AST/Identifier.h" +#include "swift/AST/Module.h" +#include "llvm/ADT/TinyPtrVector.h" + +namespace swift { + +/// Base class for infix operator and precedence group lookup results. +template +class OperatorLookupResultBase { +protected: + const DeclContext *ModuleDC; + Identifier Name; + TinyPtrVector Results; + +private: + const Derived &asDerived() const { + return *static_cast(this); + } + +public: + OperatorLookupResultBase(const DeclContext *moduleDC, Identifier name, + TinyPtrVector &&results) + : ModuleDC(moduleDC), Name(name), Results(std::move(results)) {} + + /// Retrieve the underlying results vector. + TinyPtrVector get() && { return std::move(Results); } + + /// If the lookup produced a single result, returns it. Otherwise returns + /// \c nullptr. + DeclTy *getSingle() const { + return Results.size() == 1 ? Results[0] : nullptr; + } + + /// If the lookup produced a single result, returns it. Otherwise, emits an + /// ambiguity or missing decl diagnostic, and returns \c nullptr. + DeclTy *getSingleOrDiagnose(SourceLoc loc, bool forBuiltin = false) const { + if (auto single = getSingle()) + return single; + + if (isAmbiguous()) { + asDerived().diagnoseAmbiguity(loc); + } else { + assert(!hasResults()); + asDerived().diagnoseMissing(loc, forBuiltin); + } + return nullptr; + } + + using const_iterator = typename decltype(Results)::const_iterator; + const_iterator begin() const { return Results.begin(); } + const_iterator end() const { return Results.end(); } + + /// Whether the lookup produced at least one result. + bool hasResults() const { return !Results.empty(); } + + /// Whether the lookup produced multiple ambiguous results. + bool isAmbiguous() const { return Results.size() > 1; } + + friend bool operator==(const OperatorLookupResultBase &lhs, + const OperatorLookupResultBase &rhs) { + return lhs.Results == rhs.Results; + } + friend bool operator!=(const OperatorLookupResultBase &lhs, + const OperatorLookupResultBase &rhs) { + return !(lhs == rhs); + } + friend void simple_display(llvm::raw_ostream &out, + const OperatorLookupResultBase &result) { + simple_display(out, result.Results); + } +}; + +/// The result of a precedence group lookup. +class PrecedenceGroupLookupResult final + : public OperatorLookupResultBase { + friend class OperatorLookupResultBase; + +public: + PrecedenceGroupLookupResult(const DeclContext *moduleDC, Identifier name, + TinyPtrVector &&results) + : OperatorLookupResultBase(moduleDC, name, std::move(results)) {} + + void diagnoseAmbiguity(SourceLoc loc) const; + void diagnoseMissing(SourceLoc loc, bool forBuiltin) const; +}; + +/// The result of an infix operator lookup. +class InfixOperatorLookupResult final + : public OperatorLookupResultBase { + friend class OperatorLookupResultBase; + +public: + InfixOperatorLookupResult(const DeclContext *moduleDC, Identifier name, + TinyPtrVector &&results) + : OperatorLookupResultBase(moduleDC, name, std::move(results)) {} + + void diagnoseAmbiguity(SourceLoc loc) const; + void diagnoseMissing(SourceLoc loc, bool forBuiltin) const; +}; + +} // end namespace swift + +#endif diff --git a/include/swift/AST/ParseRequests.h b/include/swift/AST/ParseRequests.h index b37e00695676e..e804023bcdd6a 100644 --- a/include/swift/AST/ParseRequests.h +++ b/include/swift/AST/ParseRequests.h @@ -19,6 +19,7 @@ #include "swift/AST/ASTTypeIDs.h" #include "swift/AST/EvaluatorDependencies.h" #include "swift/AST/SimpleRequest.h" +#include "swift/Syntax/SyntaxNodes.h" namespace swift { @@ -81,10 +82,17 @@ class ParseAbstractFunctionBodyRequest : void cacheResult(BraceStmt *value) const; }; +struct SourceFileParsingResult { + ArrayRef TopLevelDecls; + Optional> CollectedTokens; + Optional InterfaceHash; + Optional SyntaxRoot; +}; + /// Parse the top-level decls of a SourceFile. class ParseSourceFileRequest : public SimpleRequest< - ParseSourceFileRequest, ArrayRef(SourceFile *), + ParseSourceFileRequest, SourceFileParsingResult(SourceFile *), RequestFlags::SeparatelyCached | RequestFlags::DependencySource> { public: using SimpleRequest::SimpleRequest; @@ -93,17 +101,17 @@ class ParseSourceFileRequest friend SimpleRequest; // Evaluation. - ArrayRef evaluate(Evaluator &evaluator, SourceFile *SF) const; + SourceFileParsingResult evaluate(Evaluator &evaluator, SourceFile *SF) const; public: // Caching. bool isCached() const { return true; } - Optional> getCachedResult() const; - void cacheResult(ArrayRef decls) const; + Optional getCachedResult() const; + void cacheResult(SourceFileParsingResult result) const; public: evaluator::DependencySource - readDependencySource(const evaluator::DependencyCollector &) const; + readDependencySource(const evaluator::DependencyRecorder &) const; }; void simple_display(llvm::raw_ostream &out, @@ -125,7 +133,7 @@ class CodeCompletionSecondPassRequest public: evaluator::DependencySource - readDependencySource(const evaluator::DependencyCollector &) const; + readDependencySource(const evaluator::DependencyRecorder &) const; }; /// The zone number for the parser. diff --git a/include/swift/AST/ParseTypeIDZone.def b/include/swift/AST/ParseTypeIDZone.def index 1c2f07e5162dc..36f95f7117bb7 100644 --- a/include/swift/AST/ParseTypeIDZone.def +++ b/include/swift/AST/ParseTypeIDZone.def @@ -23,5 +23,5 @@ SWIFT_REQUEST(Parse, ParseAbstractFunctionBodyRequest, BraceStmt *(AbstractFunctionDecl *), SeparatelyCached, NoLocationInfo) SWIFT_REQUEST(Parse, ParseSourceFileRequest, - ArrayRef(SourceFile *), SeparatelyCached, + SourceFileParsingResult(SourceFile *), SeparatelyCached, NoLocationInfo) diff --git a/include/swift/AST/Pattern.h b/include/swift/AST/Pattern.h index 7b11705882afb..a5005df8d7ddf 100644 --- a/include/swift/AST/Pattern.h +++ b/include/swift/AST/Pattern.h @@ -24,7 +24,6 @@ #include "swift/Basic/LLVM.h" #include "swift/AST/Type.h" #include "swift/AST/Types.h" -#include "swift/AST/TypeLoc.h" #include "swift/AST/TypeAlignments.h" #include "swift/Basic/InlineBitfield.h" #include "swift/Basic/OptionSet.h" @@ -35,6 +34,7 @@ namespace swift { class Expr; enum class CheckedCastKind : unsigned; class TypeExpr; + class TypeLoc; /// PatternKind - The classification of different kinds of /// value-matching pattern. @@ -470,19 +470,14 @@ class IsPattern : public Pattern { CheckedCastKind CastKind; /// The type being checked for. - TypeLoc CastType; + TypeExpr *CastType; public: - IsPattern(SourceLoc IsLoc, TypeLoc CastTy, - Pattern *SubPattern, - CheckedCastKind Kind) - : Pattern(PatternKind::Is), - IsLoc(IsLoc), - SubPattern(SubPattern), - CastKind(Kind), - CastType(CastTy) { - assert(IsLoc.isValid() == CastTy.hasLocation()); - } + IsPattern(SourceLoc IsLoc, TypeExpr *CastTy, Pattern *SubPattern, + CheckedCastKind Kind); + + static IsPattern *createImplicit(ASTContext &Ctx, Type castTy, + Pattern *SubPattern, CheckedCastKind Kind); CheckedCastKind getCastKind() const { return CastKind; } void setCastKind(CheckedCastKind kind) { CastKind = kind; } @@ -493,16 +488,11 @@ class IsPattern : public Pattern { void setSubPattern(Pattern *p) { SubPattern = p; } SourceLoc getLoc() const { return IsLoc; } - SourceRange getSourceRange() const { - SourceLoc beginLoc = - SubPattern ? SubPattern->getSourceRange().Start : IsLoc; - SourceLoc endLoc = - (isImplicit() ? beginLoc : CastType.getSourceRange().End); - return { beginLoc, endLoc }; - } + SourceRange getSourceRange() const; - TypeLoc &getCastTypeLoc() { return CastType; } - TypeLoc getCastTypeLoc() const { return CastType; } + void setCastType(Type castTy); + Type getCastType() const; + TypeRepr *getCastTypeRepr() const; static bool classof(const Pattern *P) { return P->getKind() == PatternKind::Is; @@ -513,7 +503,7 @@ class IsPattern : public Pattern { /// case, then the value is extracted. If there is a subpattern, it is then /// matched against the associated value for the case. class EnumElementPattern : public Pattern { - TypeLoc ParentType; + TypeExpr *ParentType; SourceLoc DotLoc; DeclNameLoc NameLoc; DeclNameRef Name; @@ -521,27 +511,23 @@ class EnumElementPattern : public Pattern { Pattern /*nullable*/ *SubPattern; public: - EnumElementPattern(TypeLoc ParentType, SourceLoc DotLoc, DeclNameLoc NameLoc, - DeclNameRef Name, EnumElementDecl *Element, - Pattern *SubPattern) - : Pattern(PatternKind::EnumElement), - ParentType(ParentType), DotLoc(DotLoc), NameLoc(NameLoc), Name(Name), - ElementDeclOrUnresolvedOriginalExpr(Element), - SubPattern(SubPattern) { } + EnumElementPattern(TypeExpr *ParentType, SourceLoc DotLoc, + DeclNameLoc NameLoc, DeclNameRef Name, + EnumElementDecl *Element, Pattern *SubPattern) + : Pattern(PatternKind::EnumElement), ParentType(ParentType), + DotLoc(DotLoc), NameLoc(NameLoc), Name(Name), + ElementDeclOrUnresolvedOriginalExpr(Element), SubPattern(SubPattern) { + assert(ParentType && "Missing parent type?"); + } /// Create an unresolved EnumElementPattern for a `.foo` pattern relying on /// contextual type. - EnumElementPattern(SourceLoc DotLoc, - DeclNameLoc NameLoc, - DeclNameRef Name, - Pattern *SubPattern, - Expr *UnresolvedOriginalExpr) - : Pattern(PatternKind::EnumElement), - ParentType(), DotLoc(DotLoc), NameLoc(NameLoc), Name(Name), - ElementDeclOrUnresolvedOriginalExpr(UnresolvedOriginalExpr), - SubPattern(SubPattern) { - - } + EnumElementPattern(SourceLoc DotLoc, DeclNameLoc NameLoc, DeclNameRef Name, + Pattern *SubPattern, Expr *UnresolvedOriginalExpr) + : Pattern(PatternKind::EnumElement), ParentType(nullptr), DotLoc(DotLoc), + NameLoc(NameLoc), Name(Name), + ElementDeclOrUnresolvedOriginalExpr(UnresolvedOriginalExpr), + SubPattern(SubPattern) {} bool hasSubPattern() const { return SubPattern; } @@ -553,10 +539,6 @@ class EnumElementPattern : public Pattern { return SubPattern; } - bool isParentTypeImplicit() { - return !ParentType.hasLocation(); - } - void setSubPattern(Pattern *p) { SubPattern = p; } DeclNameRef getName() const { return Name; } @@ -577,21 +559,14 @@ class EnumElementPattern : public Pattern { DeclNameLoc getNameLoc() const { return NameLoc; } SourceLoc getLoc() const { return NameLoc.getBaseNameLoc(); } - SourceLoc getStartLoc() const { - return ParentType.hasLocation() ? ParentType.getSourceRange().Start : - DotLoc.isValid() ? DotLoc - : NameLoc.getBaseNameLoc(); - } - SourceLoc getEndLoc() const { - if (SubPattern && SubPattern->getSourceRange().isValid()) { - return SubPattern->getSourceRange().End; - } - return NameLoc.getEndLoc(); - } + SourceLoc getStartLoc() const; + SourceLoc getEndLoc() const; SourceRange getSourceRange() const { return {getStartLoc(), getEndLoc()}; } - TypeLoc &getParentType() { return ParentType; } - TypeLoc getParentType() const { return ParentType; } + TypeRepr *getParentTypeRepr() const; + + void setParentType(Type ty); + Type getParentType() const; static bool classof(const Pattern *P) { return P->getKind() == PatternKind::EnumElement; diff --git a/include/swift/AST/PrettyStackTrace.h b/include/swift/AST/PrettyStackTrace.h index ace327d4ead5b..51d047ecbb1b5 100644 --- a/include/swift/AST/PrettyStackTrace.h +++ b/include/swift/AST/PrettyStackTrace.h @@ -38,22 +38,24 @@ namespace swift { class TypeRepr; void printSourceLocDescription(llvm::raw_ostream &out, SourceLoc loc, - ASTContext &Context, bool addNewline = true); + const ASTContext &Context, + bool addNewline = true); /// PrettyStackTraceLocation - Observe that we are doing some /// processing starting at a fixed location. class PrettyStackTraceLocation : public llvm::PrettyStackTraceEntry { - ASTContext &Context; + const ASTContext &Context; SourceLoc Loc; const char *Action; public: - PrettyStackTraceLocation(ASTContext &C, const char *action, SourceLoc loc) + PrettyStackTraceLocation(const ASTContext &C, const char *action, + SourceLoc loc) : Context(C), Loc(loc), Action(action) {} virtual void print(llvm::raw_ostream &OS) const; }; void printDeclDescription(llvm::raw_ostream &out, const Decl *D, - ASTContext &Context, bool addNewline = true); + const ASTContext &Context, bool addNewline = true); /// PrettyStackTraceDecl - Observe that we are processing a specific /// declaration. @@ -78,60 +80,60 @@ class PrettyStackTraceAnyFunctionRef : public llvm::PrettyStackTraceEntry { }; void printExprDescription(llvm::raw_ostream &out, Expr *E, - ASTContext &Context, bool addNewline = true); + const ASTContext &Context, bool addNewline = true); /// PrettyStackTraceExpr - Observe that we are processing a specific /// expression. class PrettyStackTraceExpr : public llvm::PrettyStackTraceEntry { - ASTContext &Context; + const ASTContext &Context; Expr *TheExpr; const char *Action; public: - PrettyStackTraceExpr(ASTContext &C, const char *action, Expr *E) + PrettyStackTraceExpr(const ASTContext &C, const char *action, Expr *E) : Context(C), TheExpr(E), Action(action) {} virtual void print(llvm::raw_ostream &OS) const; }; void printStmtDescription(llvm::raw_ostream &out, Stmt *S, - ASTContext &Context, bool addNewline = true); + const ASTContext &Context, bool addNewline = true); /// PrettyStackTraceStmt - Observe that we are processing a specific /// statement. class PrettyStackTraceStmt : public llvm::PrettyStackTraceEntry { - ASTContext &Context; + const ASTContext &Context; Stmt *TheStmt; const char *Action; public: - PrettyStackTraceStmt(ASTContext &C, const char *action, Stmt *S) + PrettyStackTraceStmt(const ASTContext &C, const char *action, Stmt *S) : Context(C), TheStmt(S), Action(action) {} virtual void print(llvm::raw_ostream &OS) const; }; void printPatternDescription(llvm::raw_ostream &out, Pattern *P, - ASTContext &Context, bool addNewline = true); + const ASTContext &Context, bool addNewline = true); /// PrettyStackTracePattern - Observe that we are processing a /// specific pattern. class PrettyStackTracePattern : public llvm::PrettyStackTraceEntry { - ASTContext &Context; + const ASTContext &Context; Pattern *ThePattern; const char *Action; public: - PrettyStackTracePattern(ASTContext &C, const char *action, Pattern *P) + PrettyStackTracePattern(const ASTContext &C, const char *action, Pattern *P) : Context(C), ThePattern(P), Action(action) {} virtual void print(llvm::raw_ostream &OS) const; }; void printTypeDescription(llvm::raw_ostream &out, Type T, - ASTContext &Context, bool addNewline = true); + const ASTContext &Context, bool addNewline = true); /// PrettyStackTraceType - Observe that we are processing a specific type. class PrettyStackTraceType : public llvm::PrettyStackTraceEntry { - ASTContext &Context; + const ASTContext &Context; Type TheType; const char *Action; public: - PrettyStackTraceType(ASTContext &C, const char *action, Type type) + PrettyStackTraceType(const ASTContext &C, const char *action, Type type) : Context(C), TheType(type), Action(action) {} virtual void print(llvm::raw_ostream &OS) const; }; @@ -149,11 +151,12 @@ class PrettyStackTraceClangType : public llvm::PrettyStackTraceEntry { /// Observe that we are processing a specific type representation. class PrettyStackTraceTypeRepr : public llvm::PrettyStackTraceEntry { - ASTContext &Context; + const ASTContext &Context; TypeRepr *TheType; const char *Action; public: - PrettyStackTraceTypeRepr(ASTContext &C, const char *action, TypeRepr *type) + PrettyStackTraceTypeRepr(const ASTContext &C, const char *action, + TypeRepr *type) : Context(C), TheType(type), Action(action) {} virtual void print(llvm::raw_ostream &OS) const; }; @@ -161,11 +164,11 @@ class PrettyStackTraceTypeRepr : public llvm::PrettyStackTraceEntry { /// PrettyStackTraceConformance - Observe that we are processing a /// specific protocol conformance. class PrettyStackTraceConformance : public llvm::PrettyStackTraceEntry { - ASTContext &Context; + const ASTContext &Context; const ProtocolConformance *Conformance; const char *Action; public: - PrettyStackTraceConformance(ASTContext &C, const char *action, + PrettyStackTraceConformance(const ASTContext &C, const char *action, const ProtocolConformance *conformance) : Context(C), Conformance(conformance), Action(action) {} virtual void print(llvm::raw_ostream &OS) const; @@ -173,7 +176,8 @@ class PrettyStackTraceConformance : public llvm::PrettyStackTraceEntry { void printConformanceDescription(llvm::raw_ostream &out, const ProtocolConformance *conformance, - ASTContext &Context, bool addNewline = true); + const ASTContext &Context, + bool addNewline = true); class PrettyStackTraceGenericSignature : public llvm::PrettyStackTraceEntry { const char *Action; diff --git a/include/swift/AST/PrintOptions.h b/include/swift/AST/PrintOptions.h index c6c17c891d810..8fdfac5488e61 100644 --- a/include/swift/AST/PrintOptions.h +++ b/include/swift/AST/PrintOptions.h @@ -232,6 +232,8 @@ struct PrintOptions { /// Whether to print unavailable parts of the AST. bool SkipUnavailable = false; + bool SkipSwiftPrivateClangDecls = false; + /// Whether to skip internal stdlib declarations. bool SkipPrivateStdlibDecls = false; @@ -435,6 +437,9 @@ struct PrintOptions { /// The information for converting archetypes to specialized types. llvm::Optional TransformContext; + /// Whether to display (Clang-)imported module names; + bool QualifyImportedTypes = false; + /// Whether cross-import overlay modules are printed with their own name (e.g. /// _MyFrameworkYourFrameworkAdditions) or that of their underlying module /// (e.g. MyFramework). @@ -445,6 +450,9 @@ struct PrintOptions { /// Whether to print parameter specifiers as 'let' and 'var'. bool PrintParameterSpecifiers = false; + /// Whether to print inheritance lists for types. + bool PrintInherited = true; + /// \see ShouldQualifyNestedDeclarations enum class QualifyNestedDeclarations { Never, @@ -515,6 +523,7 @@ struct PrintOptions { PrintOptions result = printForDiagnostics(); result.SkipUnavailable = true; result.SkipImplicit = true; + result.SkipSwiftPrivateClangDecls = true; result.SkipPrivateStdlibDecls = true; result.SkipUnderscoredStdlibProtocols = true; result.SkipDeinit = true; diff --git a/include/swift/AST/ProtocolConformance.h b/include/swift/AST/ProtocolConformance.h index f5fa29f0f6be4..1136fb5be73cd 100644 --- a/include/swift/AST/ProtocolConformance.h +++ b/include/swift/AST/ProtocolConformance.h @@ -27,8 +27,6 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/TinyPtrVector.h" #include namespace swift { diff --git a/include/swift/AST/ReferencedNameTracker.h b/include/swift/AST/ReferencedNameTracker.h deleted file mode 100644 index cf61fe5c06b99..0000000000000 --- a/include/swift/AST/ReferencedNameTracker.h +++ /dev/null @@ -1,83 +0,0 @@ -//===--- ReferencedNameTracker.h - Records looked-up names ------*- C++ -*-===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#ifndef SWIFT_REFERENCEDNAMETRACKER_H -#define SWIFT_REFERENCEDNAMETRACKER_H - -#include "swift/AST/Identifier.h" -#include "swift/Basic/ReferenceDependencyKeys.h" -#include "llvm/ADT/DenseMap.h" - -#include - -namespace swift { - -class NominalTypeDecl; -class DependencyTracker; - -class ReferencedNameTracker { -public: - using EnumerateUsedDecl = function_ref; - -private: -#define TRACKED_SET(KIND, NAME) \ -private: \ - llvm::DenseMap NAME##s; \ - \ -public: \ - void add##NAME(KIND new##NAME, bool isCascadingUse) { \ - NAME##s[new##NAME] |= isCascadingUse; \ - } \ - /* make private once ReferenceDependencies.cpp is gone */ \ - const decltype(NAME##s) &get##NAME##s() const { return NAME##s; } - - TRACKED_SET(DeclBaseName, TopLevelName) - TRACKED_SET(DeclBaseName, DynamicLookupName) - - using MemberPair = std::pair; - TRACKED_SET(MemberPair, UsedMember) - -#undef TRACKED_SET -public: - // Pushing the DependencyTracker through unifies external dependency - // enumeration. - void enumerateAllUses(bool includeIntrafileDeps, - const DependencyTracker &depTracker, - EnumerateUsedDecl enumerateUsedDecl) const; - -private: - template - void enumerateSimpleUses(llvm::DenseMap cascadesByName, - EnumerateUsedDecl enumerateUsedDecl) const; - - void enumerateExternalUses(const DependencyTracker &, - EnumerateUsedDecl enumerateUsedDecl) const; - - void enumerateCompoundUses(bool includeIntrafileDeps, - EnumerateUsedDecl enumerateUsedDecl) const; - - std::unordered_set - computeHoldersOfCascadingMembers(bool includeIntrafileDeps) const; - - void enumerateNominalUses( - bool includeIntrafileDeps, - const std::unordered_set &&holdersOfCascadingMembers, - EnumerateUsedDecl enumerateUsedDecl) const; - - void enumerateMemberUses(EnumerateUsedDecl enumerateUsedDecl) const; -}; - -} // end namespace swift - -#endif // LLVM_SWIFT_REFERENCEDNAMETRACKER_H diff --git a/include/swift/AST/SILGenRequests.h b/include/swift/AST/SILGenRequests.h index 3f93c5608ed7b..1c0ca21216b63 100644 --- a/include/swift/AST/SILGenRequests.h +++ b/include/swift/AST/SILGenRequests.h @@ -40,38 +40,39 @@ template void reportEvaluatedRequest(UnifiedStatsReporter &stats, const Request &request); -struct SILGenDescriptor { +/// Describes a file or module to be lowered to SIL. +struct ASTLoweringDescriptor { llvm::PointerUnion context; Lowering::TypeConverter &conv; const SILOptions &opts; - friend llvm::hash_code hash_value(const SILGenDescriptor &owner) { + friend llvm::hash_code hash_value(const ASTLoweringDescriptor &owner) { return llvm::hash_combine(owner.context, (void *)&owner.conv, (void *)&owner.opts); } - friend bool operator==(const SILGenDescriptor &lhs, - const SILGenDescriptor &rhs) { + friend bool operator==(const ASTLoweringDescriptor &lhs, + const ASTLoweringDescriptor &rhs) { return lhs.context == rhs.context && &lhs.conv == &rhs.conv && &lhs.opts == &rhs.opts; } - friend bool operator!=(const SILGenDescriptor &lhs, - const SILGenDescriptor &rhs) { + friend bool operator!=(const ASTLoweringDescriptor &lhs, + const ASTLoweringDescriptor &rhs) { return !(lhs == rhs); } public: - static SILGenDescriptor forFile(FileUnit &sf, Lowering::TypeConverter &conv, - const SILOptions &opts) { - return SILGenDescriptor{&sf, conv, opts}; + static ASTLoweringDescriptor + forFile(FileUnit &sf, Lowering::TypeConverter &conv, const SILOptions &opts) { + return ASTLoweringDescriptor{&sf, conv, opts}; } - static SILGenDescriptor forWholeModule(ModuleDecl *mod, - Lowering::TypeConverter &conv, - const SILOptions &opts) { - return SILGenDescriptor{mod, conv, opts}; + static ASTLoweringDescriptor forWholeModule(ModuleDecl *mod, + Lowering::TypeConverter &conv, + const SILOptions &opts) { + return ASTLoweringDescriptor{mod, conv, opts}; } /// For a single file input, returns a single element array containing that @@ -83,13 +84,17 @@ struct SILGenDescriptor { SourceFile *getSourceFileToParse() const; }; -void simple_display(llvm::raw_ostream &out, const SILGenDescriptor &d); +void simple_display(llvm::raw_ostream &out, const ASTLoweringDescriptor &d); -SourceLoc extractNearestSourceLoc(const SILGenDescriptor &desc); +SourceLoc extractNearestSourceLoc(const ASTLoweringDescriptor &desc); -class SILGenerationRequest +/// Lowers a file or module to SIL. In most cases this involves transforming +/// a file's AST into SIL, through SILGen. However it can also handle files +/// containing SIL in textual or binary form, which will be parsed or +/// deserialized as needed. +class ASTLoweringRequest : public SimpleRequest< - SILGenerationRequest, std::unique_ptr(SILGenDescriptor), + ASTLoweringRequest, std::unique_ptr(ASTLoweringDescriptor), RequestFlags::Uncached | RequestFlags::DependencySource> { public: using SimpleRequest::SimpleRequest; @@ -98,19 +103,19 @@ class SILGenerationRequest friend SimpleRequest; // Evaluation. - std::unique_ptr - evaluate(Evaluator &evaluator, SILGenDescriptor desc) const; + std::unique_ptr evaluate(Evaluator &evaluator, + ASTLoweringDescriptor desc) const; public: // Incremental dependencies. evaluator::DependencySource - readDependencySource(const evaluator::DependencyCollector &) const; + readDependencySource(const evaluator::DependencyRecorder &) const; }; /// Parses a .sil file into a SILModule. class ParseSILModuleRequest : public SimpleRequest(SILGenDescriptor), + std::unique_ptr(ASTLoweringDescriptor), RequestFlags::Uncached> { public: using SimpleRequest::SimpleRequest; @@ -119,8 +124,8 @@ class ParseSILModuleRequest friend SimpleRequest; // Evaluation. - std::unique_ptr - evaluate(Evaluator &evaluator, SILGenDescriptor desc) const; + std::unique_ptr evaluate(Evaluator &evaluator, + ASTLoweringDescriptor desc) const; }; /// The zone number for SILGen. diff --git a/include/swift/AST/SILGenTypeIDZone.def b/include/swift/AST/SILGenTypeIDZone.def index d2fed923440ba..6c661a6d7965b 100644 --- a/include/swift/AST/SILGenTypeIDZone.def +++ b/include/swift/AST/SILGenTypeIDZone.def @@ -14,9 +14,9 @@ // //===----------------------------------------------------------------------===// -SWIFT_REQUEST(SILGen, SILGenerationRequest, - std::unique_ptr(SILGenDescriptor), +SWIFT_REQUEST(SILGen, ASTLoweringRequest, + std::unique_ptr(ASTLoweringDescriptor), Uncached, NoLocationInfo) SWIFT_REQUEST(SILGen, ParseSILModuleRequest, - std::unique_ptr(SILGenDescriptor), + std::unique_ptr(ASTLoweringDescriptor), Uncached, NoLocationInfo) diff --git a/include/swift/AST/SearchPathOptions.h b/include/swift/AST/SearchPathOptions.h index 86d9567553186..36fc930d589ef 100644 --- a/include/swift/AST/SearchPathOptions.h +++ b/include/swift/AST/SearchPathOptions.h @@ -82,6 +82,9 @@ class SearchPathOptions { /// would for a non-system header. bool DisableModulesValidateSystemDependencies = false; + /// The paths to a set of explicitly built modules from interfaces. + std::vector ExplicitSwiftModules; + private: static StringRef pathStringFromFrameworkSearchPath(const FrameworkSearchPath &next) { diff --git a/include/swift/AST/SemanticAttrs.def b/include/swift/AST/SemanticAttrs.def index 81615e37d9c10..a77a6b295ad24 100644 --- a/include/swift/AST/SemanticAttrs.def +++ b/include/swift/AST/SemanticAttrs.def @@ -51,6 +51,7 @@ SEMANTICS_ATTR(ARRAY_GET_ELEMENT_ADDRESS, "array.get_element_address") SEMANTICS_ATTR(ARRAY_INIT, "array.init") SEMANTICS_ATTR(ARRAY_INIT_EMPTY, "array.init.empty") SEMANTICS_ATTR(ARRAY_MAKE_MUTABLE, "array.make_mutable") +SEMANTICS_ATTR(ARRAY_END_MUTATION, "array.end_mutation") SEMANTICS_ATTR(ARRAY_MUTATE_UNKNOWN, "array.mutate_unknown") SEMANTICS_ATTR(ARRAY_PROPS_IS_NATIVE_TYPE_CHECKED, "array.props.isNativeTypeChecked") SEMANTICS_ATTR(ARRAY_RESERVE_CAPACITY_FOR_APPEND, "array.reserve_capacity_for_append") @@ -59,6 +60,7 @@ SEMANTICS_ATTR(ARRAY_WITH_UNSAFE_MUTABLE_BUFFER_POINTER, "array.withUnsafeMutabl SEMANTICS_ATTR(ARRAY_COUNT, "array.count") SEMANTICS_ATTR(ARRAY_DEALLOC_UNINITIALIZED, "array.dealloc_uninitialized") SEMANTICS_ATTR(ARRAY_UNINITIALIZED_INTRINSIC, "array.uninitialized_intrinsic") +SEMANTICS_ATTR(ARRAY_FINALIZE_INTRINSIC, "array.finalize_intrinsic") SEMANTICS_ATTR(SEQUENCE_FOR_EACH, "sequence.forEach") @@ -67,6 +69,8 @@ SEMANTICS_ATTR(OPTIMIZE_SIL_SPECIALIZE_GENERIC_PARTIAL_NEVER, "optimize.sil.specialize.generic.partial.never") SEMANTICS_ATTR(OPTIMIZE_SIL_SPECIALIZE_GENERIC_SIZE_NEVER, "optimize.sil.specialize.generic.size.never") +SEMANTICS_ATTR(OPTIMIZE_SIL_SPECIALIZE_OWNED2GUARANTEE_NEVER, + "optimize.sil.specialize.owned2guarantee.never") SEMANTICS_ATTR(OSLOG_MESSAGE_INIT_INTERPOLATION, "oslog.message.init_interpolation") SEMANTICS_ATTR(OSLOG_MESSAGE_INIT_STRING_LITERAL, "oslog.message.init_stringliteral") diff --git a/include/swift/AST/SemanticAttrs.h b/include/swift/AST/SemanticAttrs.h index b6b9926ca8165..7fe7c38644dee 100644 --- a/include/swift/AST/SemanticAttrs.h +++ b/include/swift/AST/SemanticAttrs.h @@ -19,6 +19,7 @@ #ifndef SWIFT_SEMANTICS_H #define SWIFT_SEMANTICS_H +#include "swift/Basic/LLVM.h" #include "llvm/ADT/StringRef.h" namespace swift { diff --git a/include/swift/AST/SimpleRequest.h b/include/swift/AST/SimpleRequest.h index 2ab9003b6d2f0..42751e142682c 100644 --- a/include/swift/AST/SimpleRequest.h +++ b/include/swift/AST/SimpleRequest.h @@ -232,7 +232,7 @@ SourceLoc extractNearestSourceLoc(const std::tuple &value) { /// the 3 caching kinds defined above. /// \code /// evaluator::DependencySource -/// readDependencySource(const evaluator::DependencyCollector &) const; +/// readDependencySource(const evaluator::DependencyRecorder &) const; /// \endcode /// /// Requests that define dependency sinks should instead override diff --git a/include/swift/AST/SourceFile.h b/include/swift/AST/SourceFile.h index 820af1095f4e9..ca305f8675db8 100644 --- a/include/swift/AST/SourceFile.h +++ b/include/swift/AST/SourceFile.h @@ -16,6 +16,8 @@ #include "swift/AST/FileUnit.h" #include "swift/AST/SynthesizedFileUnit.h" #include "swift/Basic/Debug.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/SmallPtrSet.h" namespace swift { @@ -30,9 +32,6 @@ class SourceFile final : public FileUnit { friend class ParseSourceFileRequest; public: - class Impl; - struct SourceFileSyntaxInfo; - /// Possible attributes for imports in source files. enum class ImportFlags { /// The imported module is exposed to anyone who imports the parent module. @@ -106,15 +105,27 @@ class SourceFile final : public FileUnit { /// decl. /// /// FIXME: When condition evaluation moves to a later phase, remove this - /// and adjust the client call 'performParseOnly'. + /// and the associated language option. DisablePoundIfEvaluation = 1 << 1, + /// Whether to build a syntax tree. + BuildSyntaxTree = 1 << 2, + + /// Whether to save the file's parsed tokens. + CollectParsedTokens = 1 << 3, + + /// Whether to compute the interface hash of the file. + EnableInterfaceHash = 1 << 4, + /// Whether to suppress warnings when parsing. This is set for secondary /// files, as they get parsed multiple times. - SuppressWarnings = 1 << 2 + SuppressWarnings = 1 << 5, }; using ParsingOptions = OptionSet; + /// Retrieve the parsing options specified in the LangOptions. + static ParsingOptions getDefaultParsingOptions(const LangOptions &langOpts); + private: std::unique_ptr Cache; SourceLookupCache &getCache() const; @@ -137,9 +148,6 @@ class SourceFile final : public FileUnit { /// This is set during type checking. TypeRefinementContext *TRC = nullptr; - /// If non-null, used to track name lookups that happen within this file. - Optional RequestReferencedNames; - /// Either the class marked \@NS/UIApplicationMain or the synthesized FuncDecl /// that calls main on the type marked @main. Decl *MainDecl = nullptr; @@ -160,6 +168,9 @@ class SourceFile final : public FileUnit { /// The parsing options for the file. ParsingOptions ParsingOpts; + /// Whether this is a primary source file which we'll be generating code for. + bool IsPrimary; + /// The scope map that describes this source file. std::unique_ptr Scope; @@ -198,7 +209,6 @@ class SourceFile final : public FileUnit { ParserStatePtr(/*ptr*/ nullptr, /*deleter*/ nullptr); friend ASTContext; - friend Impl; public: /// Appends the given declaration to the end of the top-level decls list. Do @@ -235,6 +245,10 @@ class SourceFile final : public FileUnit { /// Retrieve the parsing options for the file. ParsingOptions getParsingOptions() const { return ParsingOpts; } + /// Whether this source file is a primary file, meaning that we're generating + /// code for it. Note this method returns \c false in WMO. + bool isPrimary() const { return IsPrimary; } + /// A cache of syntax nodes that can be reused when creating the syntax tree /// for this file. swift::SyntaxParsingCache *SyntaxParsingCache = nullptr; @@ -309,8 +323,7 @@ class SourceFile final : public FileUnit { llvm::StringMap getInfoForUsedFilePaths() const; SourceFile(ModuleDecl &M, SourceFileKind K, Optional bufferID, - bool KeepParsedTokens = false, bool KeepSyntaxTree = false, - ParsingOptions parsingOpts = {}); + ParsingOptions parsingOpts = {}, bool isPrimary = false); ~SourceFile(); @@ -343,8 +356,9 @@ class SourceFile final : public FileUnit { /// Find all SPI names imported from \p importedModule by this file, /// collecting the identifiers in \p spiGroups. virtual void - lookupImportedSPIGroups(const ModuleDecl *importedModule, - SmallVectorImpl &spiGroups) const override; + lookupImportedSPIGroups( + const ModuleDecl *importedModule, + llvm::SmallSetVector &spiGroups) const override; // Is \p targetDecl accessible as an explictly imported SPI from this file? bool isImportedAsSPI(const ValueDecl *targetDecl) const; @@ -439,25 +453,6 @@ class SourceFile final : public FileUnit { virtual bool walk(ASTWalker &walker) override; - ReferencedNameTracker *getRequestBasedReferencedNameTracker() { - return RequestReferencedNames ? RequestReferencedNames.getPointer() : nullptr; - } - const ReferencedNameTracker *getRequestBasedReferencedNameTracker() const { - return RequestReferencedNames ? RequestReferencedNames.getPointer() : nullptr; - } - - /// Creates and installs the referenced name trackers in this source file. - /// - /// This entrypoint must be called before incremental compilation can proceed, - /// else reference dependencies will not be registered. - void createReferencedNameTracker(); - - /// Retrieves the appropriate referenced name tracker instance. - /// - /// If incremental dependencies tracking is not enabled or \c createReferencedNameTracker() - /// has not been invoked on this source file, the result is \c nullptr. - const ReferencedNameTracker *getConfiguredReferencedNameTracker() const; - /// The buffer ID for the file that was imported, or None if there /// is no associated buffer. Optional getBufferID() const { @@ -495,7 +490,7 @@ class SourceFile final : public FileUnit { } SWIFT_DEBUG_DUMP; - void dump(raw_ostream &os) const; + void dump(raw_ostream &os, bool parseIfNeeded = false) const; /// Pretty-print the contents of this source file. /// @@ -558,26 +553,13 @@ class SourceFile final : public FileUnit { /// Set the root refinement context for the file. void setTypeRefinementContext(TypeRefinementContext *TRC); - void enableInterfaceHash() { - assert(!hasInterfaceHash()); - InterfaceHash.emplace(); - } - + /// Whether this file has an interface hash available. bool hasInterfaceHash() const { - return InterfaceHash.hasValue(); + return ParsingOpts.contains(ParsingFlags::EnableInterfaceHash); } - NullablePtr getInterfaceHashPtr() { - return InterfaceHash ? InterfaceHash.getPointer() : nullptr; - } - - void getInterfaceHash(llvm::SmallString<32> &str) const { - // Copy to preserve idempotence. - llvm::MD5 md5 = *InterfaceHash; - llvm::MD5::MD5Result result; - md5.final(result); - llvm::MD5::stringifyResult(result, str); - } + /// Output this file's interface hash into the provided string buffer. + void getInterfaceHash(llvm::SmallString<32> &str) const; void dumpInterfaceHash(llvm::raw_ostream &out) { llvm::SmallString<32> str; @@ -585,23 +567,21 @@ class SourceFile final : public FileUnit { out << str << '\n'; } - std::vector &getTokenVector(); - + /// If this source file has been told to collect its parsed tokens, retrieve + /// those tokens. ArrayRef getAllTokens() const; - bool shouldCollectToken() const; + /// Whether the parsed tokens of this source file should be saved, allowing + /// them to be accessed from \c getAllTokens. + bool shouldCollectTokens() const; bool shouldBuildSyntaxTree() const; - bool canBeParsedInFull() const; - /// Whether the bodies of types and functions within this file can be lazily /// parsed. bool hasDelayedBodyParsing() const; syntax::SourceFileSyntax getSyntaxRoot() const; - void setSyntaxRoot(syntax::SourceFileSyntax &&Root); - bool hasSyntaxRoot() const; OpaqueTypeDecl *lookupOpaqueResultType(StringRef MangledName) override; @@ -616,10 +596,12 @@ class SourceFile final : public FileUnit { private: - /// If not None, the underlying vector should contain tokens of this source file. - Optional> AllCorrectedTokens; + /// If not \c None, the underlying vector contains the parsed tokens of this + /// source file. + Optional> AllCollectedTokens; - std::unique_ptr SyntaxInfo; + /// The root of the syntax tree representing the source file. + std::unique_ptr SyntaxRoot; }; inline SourceFile::ParsingOptions operator|(SourceFile::ParsingFlags lhs, diff --git a/include/swift/AST/Stmt.h b/include/swift/AST/Stmt.h index a9bece28862f5..513be8e40d774 100644 --- a/include/swift/AST/Stmt.h +++ b/include/swift/AST/Stmt.h @@ -25,7 +25,6 @@ #include "swift/AST/TypeAlignments.h" #include "swift/Basic/Debug.h" #include "swift/Basic/NullablePtr.h" -#include "llvm/ADT/TinyPtrVector.h" #include "llvm/Support/TrailingObjects.h" namespace swift { @@ -539,11 +538,11 @@ class LabeledStmt : public Stmt { /// DoStmt - do statement, without any trailing clauses. class DoStmt : public LabeledStmt { SourceLoc DoLoc; - Stmt *Body; + BraceStmt *Body; public: DoStmt(LabeledStmtInfo labelInfo, SourceLoc doLoc, - Stmt *body, Optional implicit = None) + BraceStmt *body, Optional implicit = None) : LabeledStmt(StmtKind::Do, getDefaultImplicitFlag(implicit, doLoc), labelInfo), DoLoc(doLoc), Body(body) {} @@ -553,8 +552,8 @@ class DoStmt : public LabeledStmt { SourceLoc getStartLoc() const { return getLabelLocOrKeywordLoc(DoLoc); } SourceLoc getEndLoc() const { return Body->getEndLoc(); } - Stmt *getBody() const { return Body; } - void setBody(Stmt *s) { Body = s; } + BraceStmt *getBody() const { return Body; } + void setBody(BraceStmt *s) { Body = s; } static bool classof(const Stmt *S) { return S->getKind() == StmtKind::Do; } }; diff --git a/include/swift/AST/Type.h b/include/swift/AST/Type.h index 2d540a9138239..1e9cf37b95fd9 100644 --- a/include/swift/AST/Type.h +++ b/include/swift/AST/Type.h @@ -386,6 +386,7 @@ class CanType : public Type { static bool isExistentialTypeImpl(CanType type); static bool isAnyExistentialTypeImpl(CanType type); static bool isObjCExistentialTypeImpl(CanType type); + static bool isTypeErasedGenericClassTypeImpl(CanType type); static CanType getOptionalObjectTypeImpl(CanType type); static CanType getReferenceStorageReferentImpl(CanType type); static CanType getWithoutSpecifierTypeImpl(CanType type); @@ -472,6 +473,11 @@ class CanType : public Type { return isObjCExistentialTypeImpl(*this); } + // Is this an ObjC generic class. + bool isTypeErasedGenericClassType() const { + return isTypeErasedGenericClassTypeImpl(*this); + } + ClassDecl *getClassOrBoundGenericClass() const; // in Types.h StructDecl *getStructOrBoundGenericStruct() const; // in Types.h EnumDecl *getEnumOrBoundGenericEnum() const; // in Types.h diff --git a/include/swift/AST/TypeAlignments.h b/include/swift/AST/TypeAlignments.h index b1b5a1bb596dc..2482500387532 100644 --- a/include/swift/AST/TypeAlignments.h +++ b/include/swift/AST/TypeAlignments.h @@ -51,7 +51,7 @@ namespace swift { class TypeVariableType; class TypeBase; class TypeDecl; - class TypeLoc; + class TypeRepr; class ValueDecl; /// We frequently use three tag bits on all of these types. @@ -64,7 +64,7 @@ namespace swift { constexpr size_t PatternAlignInBits = 3; constexpr size_t SILFunctionAlignInBits = 2; constexpr size_t TypeVariableAlignInBits = 4; - constexpr size_t TypeLocAlignInBits = 3; + constexpr size_t TypeReprAlignInBits = 3; } namespace llvm { @@ -126,7 +126,7 @@ LLVM_DECLARE_TYPE_ALIGNMENT(swift::SILFunction, LLVM_DECLARE_TYPE_ALIGNMENT(swift::AttributeBase, swift::AttrAlignInBits) -LLVM_DECLARE_TYPE_ALIGNMENT(swift::TypeLoc, swift::TypeLocAlignInBits) +LLVM_DECLARE_TYPE_ALIGNMENT(swift::TypeRepr, swift::TypeReprAlignInBits) static_assert(alignof(void*) >= 2, "pointer alignment is too small"); diff --git a/include/swift/AST/TypeCheckRequests.h b/include/swift/AST/TypeCheckRequests.h index 3d96d17924add..75392765ce473 100644 --- a/include/swift/AST/TypeCheckRequests.h +++ b/include/swift/AST/TypeCheckRequests.h @@ -123,7 +123,7 @@ class SuperclassTypeRequest public: // Incremental dependencies evaluator::DependencySource - readDependencySource(const evaluator::DependencyCollector &e) const; + readDependencySource(const evaluator::DependencyRecorder &e) const; void writeDependencySink(evaluator::DependencyCollector &tracker, Type t) const; }; @@ -867,14 +867,13 @@ class LazyStoragePropertyRequest : bool isCached() const { return true; } }; -/// Request to type check the body of the given function up to the given -/// source location. +/// Request to type check the body of the given function. /// /// Produces true if an error occurred, false otherwise. /// FIXME: it would be far better to return the type-checked body. -class TypeCheckFunctionBodyUntilRequest : - public SimpleRequest { public: using SimpleRequest::SimpleRequest; @@ -883,9 +882,7 @@ class TypeCheckFunctionBodyUntilRequest : friend SimpleRequest; // Evaluation. - bool - evaluate(Evaluator &evaluator, AbstractFunctionDecl *func, - SourceLoc endTypeCheckLoc) const; + bool evaluate(Evaluator &evaluator, AbstractFunctionDecl *func) const; public: bool isCached() const { return true; } @@ -893,7 +890,25 @@ class TypeCheckFunctionBodyUntilRequest : public: // Incremental dependencies. evaluator::DependencySource - readDependencySource(const evaluator::DependencyCollector &) const; + readDependencySource(const evaluator::DependencyRecorder &) const; +}; + +/// Request to typecheck a function body element at the given source location. +/// +/// Produces true if an error occurred, false otherwise. +class TypeCheckFunctionBodyAtLocRequest + : public SimpleRequest { +public: + using SimpleRequest::SimpleRequest; + +private: + friend SimpleRequest; + + // Evaluation. + bool evaluate(Evaluator &evaluator, AbstractFunctionDecl *func, + SourceLoc Loc) const; }; /// Request to obtain a list of stored properties in a nominal type. @@ -1531,7 +1546,8 @@ void simple_display(llvm::raw_ostream &out, const PrecedenceGroupDescriptor &d); class ValidatePrecedenceGroupRequest : public SimpleRequest( + PrecedenceGroupDescriptor), RequestFlags::Cached> { public: using SimpleRequest::SimpleRequest; @@ -1540,7 +1556,7 @@ class ValidatePrecedenceGroupRequest friend SimpleRequest; // Evaluation. - PrecedenceGroupDecl * + TinyPtrVector evaluate(Evaluator &evaluator, PrecedenceGroupDescriptor descriptor) const; public: @@ -2034,7 +2050,7 @@ class TypeCheckSourceFileRequest public: // Incremental dependencies. evaluator::DependencySource - readDependencySource(const evaluator::DependencyCollector &) const; + readDependencySource(const evaluator::DependencyRecorder &) const; }; /// Computes whether the specified type or a super-class/super-protocol has the @@ -2239,7 +2255,7 @@ class ClosureHasExplicitResultRequest bool isCached() const { return true; } }; -using ProtocolConformanceLookupResult = SmallVector; +using ProtocolConformanceLookupResult = std::vector; void simple_display(llvm::raw_ostream &out, ConformanceLookupKind kind); /// Lookup and expand all conformances in the given context. @@ -2261,7 +2277,7 @@ class LookupAllConformancesInContextRequest : public SimpleRequest { public: @@ -2275,9 +2291,11 @@ class LookupAllConformancesInContextRequest evaluate(Evaluator &evaluator, const IterableDeclContext *IDC) const; public: + bool isCached() const { return true; } + // Incremental dependencies evaluator::DependencySource - readDependencySource(const evaluator::DependencyCollector &eval) const; + readDependencySource(const evaluator::DependencyRecorder &eval) const; void writeDependencySink(evaluator::DependencyCollector &tracker, ProtocolConformanceLookupResult r) const; }; @@ -2305,7 +2323,7 @@ class CheckRedeclarationRequest public: evaluator::DependencySource - readDependencySource(const evaluator::DependencyCollector &eval) const; + readDependencySource(const evaluator::DependencyRecorder &eval) const; void writeDependencySink(evaluator::DependencyCollector &tracker, evaluator::SideEffect) const; }; @@ -2456,6 +2474,80 @@ class CheckInconsistentImplementationOnlyImportsRequest bool isCached() const { return true; } }; +/// Retrieves the primary source files in the main module. +// FIXME: This isn't really a type-checking request, if we ever split off a +// zone for more basic AST requests, this should be moved there. +class PrimarySourceFilesRequest + : public SimpleRequest(ModuleDecl *), + RequestFlags::Cached> { +public: + using SimpleRequest::SimpleRequest; + +private: + friend SimpleRequest; + + ArrayRef evaluate(Evaluator &evaluator, ModuleDecl *mod) const; + +public: + // Cached. + bool isCached() const { return true; } +}; + +/// Retrieve the file being used for code completion in the main module. +// FIXME: This isn't really a type-checking request, if we ever split off a +// zone for more basic AST requests, this should be moved there. +class CodeCompletionFileRequest + : public SimpleRequest { +public: + using SimpleRequest::SimpleRequest; + +private: + friend SimpleRequest; + + SourceFile *evaluate(Evaluator &evaluator, ModuleDecl *mod) const; + +public: + // Cached. + bool isCached() const { return true; } +}; + +/// Kinds of types for CustomAttr. +enum class CustomAttrTypeKind { + /// The type is required to not be expressed in terms of + /// any contextual type parameters. + NonGeneric, + + /// Property delegates have some funky rules, like allowing + /// unbound generic types. + PropertyDelegate, +}; + +void simple_display(llvm::raw_ostream &out, CustomAttrTypeKind value); + +class CustomAttrTypeRequest + : public SimpleRequest { +public: + using SimpleRequest::SimpleRequest; + +private: + friend SimpleRequest; + + // Evaluation. + Type evaluate(Evaluator &evaluator, CustomAttr *, DeclContext *, + CustomAttrTypeKind) const; + +public: + // Separate caching. + bool isCached() const { return true; } + Optional getCachedResult() const; + void cacheResult(Type value) const; +}; + // Allow AnyValue to compare two Type values, even though Type doesn't // support ==. template<> diff --git a/include/swift/AST/TypeCheckerTypeIDZone.def b/include/swift/AST/TypeCheckerTypeIDZone.def index f69a109bf4693..4df761af7c2d2 100644 --- a/include/swift/AST/TypeCheckerTypeIDZone.def +++ b/include/swift/AST/TypeCheckerTypeIDZone.def @@ -36,9 +36,14 @@ SWIFT_REQUEST(TypeChecker, CheckRedeclarationRequest, Uncached, NoLocationInfo) SWIFT_REQUEST(TypeChecker, ClassAncestryFlagsRequest, AncestryFlags(ClassDecl *), Cached, NoLocationInfo) +SWIFT_REQUEST(TypeChecker, CodeCompletionFileRequest, + SourceFile *(ModuleDecl *), Cached, NoLocationInfo) SWIFT_REQUEST(TypeChecker, CompareDeclSpecializationRequest, bool (DeclContext *, ValueDecl *, ValueDecl *, bool), Cached, NoLocationInfo) +SWIFT_REQUEST(TypeChecker, CustomAttrTypeRequest, + Type(CustomAttr *, DeclContext *, CustomAttrTypeKind), + SeparatelyCached, NoLocationInfo) SWIFT_REQUEST(TypeChecker, DefaultArgumentExprRequest, Expr *(ParamDecl *), SeparatelyCached, NoLocationInfo) SWIFT_REQUEST(TypeChecker, DefaultArgumentInitContextRequest, @@ -151,6 +156,8 @@ SWIFT_REQUEST(TypeChecker, OverriddenDeclsRequest, SWIFT_REQUEST(TypeChecker, PatternBindingEntryRequest, const PatternBindingEntry *(PatternBindingDecl *, unsigned), SeparatelyCached, NoLocationInfo) +SWIFT_REQUEST(TypeChecker, PrimarySourceFilesRequest, + ArrayRef(ModuleDecl *), Cached, NoLocationInfo) SWIFT_REQUEST(TypeChecker, PropertyWrapperBackingPropertyInfoRequest, PropertyWrapperBackingPropertyInfo(VarDecl *), Cached, NoLocationInfo) @@ -196,9 +203,11 @@ SWIFT_REQUEST(TypeChecker, SuperclassTypeRequest, SWIFT_REQUEST(TypeChecker, SynthesizeAccessorRequest, AccessorDecl *(AbstractStorageDecl *, AccessorKind), SeparatelyCached, NoLocationInfo) -SWIFT_REQUEST(TypeChecker, TypeCheckFunctionBodyUntilRequest, +SWIFT_REQUEST(TypeChecker, TypeCheckFunctionBodyRequest, + bool(AbstractFunctionDecl *), Cached, NoLocationInfo) +SWIFT_REQUEST(TypeChecker, TypeCheckFunctionBodyAtLocRequest, bool(AbstractFunctionDecl *, SourceLoc), - Cached, NoLocationInfo) + Uncached, NoLocationInfo) SWIFT_REQUEST(TypeChecker, UnderlyingTypeRequest, Type(TypeAliasDecl *), SeparatelyCached, NoLocationInfo) SWIFT_REQUEST(TypeChecker, USRGenerationRequest, std::string(const ValueDecl *), diff --git a/include/swift/AST/TypeLoc.h b/include/swift/AST/TypeLoc.h index 50218e2844ede..2f8007dda9900 100644 --- a/include/swift/AST/TypeLoc.h +++ b/include/swift/AST/TypeLoc.h @@ -29,7 +29,7 @@ class TypeRepr; /// TypeLoc - Provides source location information for a parsed type. /// A TypeLoc is stored in AST nodes which use an explicitly written type. -class alignas(1 << TypeLocAlignInBits) TypeLoc { +class alignas(1 << TypeReprAlignInBits) TypeLoc final { Type Ty; TypeRepr *TyR = nullptr; @@ -65,8 +65,6 @@ class alignas(1 << TypeLocAlignInBits) TypeLoc { void setInvalidType(ASTContext &C); void setType(Type Ty); - TypeLoc clone(ASTContext &ctx) const; - friend llvm::hash_code hash_value(const TypeLoc &owner) { return llvm::hash_combine(owner.Ty.getPointer(), owner.TyR); } diff --git a/include/swift/AST/TypeRepr.h b/include/swift/AST/TypeRepr.h index 14e99ea6225e9..3e618c88802b2 100644 --- a/include/swift/AST/TypeRepr.h +++ b/include/swift/AST/TypeRepr.h @@ -48,7 +48,7 @@ enum : unsigned { NumTypeReprKindBits = countBitsUsed(static_cast(TypeReprKind::Last_TypeRepr)) }; /// Representation of a type as written in source. -class alignas(8) TypeRepr { +class alignas(1 << TypeReprAlignInBits) TypeRepr { TypeRepr(const TypeRepr&) = delete; void operator=(const TypeRepr&) = delete; @@ -163,9 +163,6 @@ class alignas(8) TypeRepr { void print(raw_ostream &OS, const PrintOptions &Opts = PrintOptions()) const; void print(ASTPrinter &Printer, const PrintOptions &Opts) const; SWIFT_DEBUG_DUMP; - - /// Clone the given type representation. - TypeRepr *clone(const ASTContext &ctx) const; }; /// A TypeRepr for a type with a syntax error. Can be used both as a diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index 0bf41995878ab..abe0baf5a6a08 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -852,7 +852,17 @@ class alignas(1 << TypeAlignInBits) TypeBase { /// \returns The superclass of this type, or a null type if it has no /// superclass. Type getSuperclass(bool useArchetypes = true); - + + /// Retrieve the root class of this type by repeatedly retrieving the + /// superclass. + /// + /// \param useArchetypes Whether to use context archetypes for outer generic + /// parameters if the class is nested inside a generic function. + /// + /// \returns The base class of this type, or this type itself if it has no + /// superclasses. + Type getRootClass(bool useArchetypes = true); + /// True if this type is the exact superclass of another type. /// /// \param ty The potential subclass. @@ -3932,13 +3942,34 @@ inline bool isIndirectFormalResult(ResultConvention convention) { return convention == ResultConvention::Indirect; } +/// The differentiability of a SIL function type result. +enum class SILResultDifferentiability : unsigned { + /// Either differentiable or not applicable. + /// + /// - If the function type is not `@differentiable`, result + /// differentiability is not applicable. This case is the default value. + /// - If the function type is `@differentiable`, the function is + /// differentiable with respect to this result. + DifferentiableOrNotApplicable, + + /// Not differentiable: a `@noDerivative` result. + /// + /// May be applied only to result of `@differentiable` function types. + /// The function type is not differentiable with respect to this result. + NotDifferentiable, +}; + /// A result type and the rules for returning it. class SILResultInfo { llvm::PointerIntPair TypeAndConvention; + SILResultDifferentiability Differentiability : 1; + public: SILResultInfo() = default; - SILResultInfo(CanType type, ResultConvention conv) - : TypeAndConvention(type, conv) { + SILResultInfo(CanType type, ResultConvention conv, + SILResultDifferentiability differentiability = + SILResultDifferentiability::DifferentiableOrNotApplicable) + : TypeAndConvention(type, conv), Differentiability(differentiability) { assert(type->isLegalSILType() && "SILResultInfo has illegal SIL type"); } @@ -3959,6 +3990,17 @@ class SILResultInfo { ResultConvention getConvention() const { return TypeAndConvention.getInt(); } + + SILResultDifferentiability getDifferentiability() const { + return Differentiability; + } + + SILResultInfo + getWithDifferentiability(SILResultDifferentiability differentiability) const { + return SILResultInfo(getInterfaceType(), getConvention(), + differentiability); + } + /// The SIL storage type determines the ABI for arguments based purely on the /// formal result conventions. The actual SIL type for the result values may /// differ in canonical SIL. In particular, opaque values require indirect @@ -4015,6 +4057,7 @@ class SILResultInfo { void profile(llvm::FoldingSetNodeID &id) { id.AddPointer(TypeAndConvention.getOpaqueValue()); + id.AddInteger((unsigned)getDifferentiability()); } SWIFT_DEBUG_DUMP; @@ -4704,24 +4747,31 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode, /// `@noDerivative` ones). IndexSubset *getDifferentiabilityParameterIndices(); + /// Given that `this` is a `@differentiable` or `@differentiable(linear)` + /// function type, returns an `IndexSubset` corresponding to the + /// differentiability/linearity results (e.g. all results except the + /// `@noDerivative` ones). + IndexSubset *getDifferentiabilityResultIndices(); + /// Returns the `@differentiable` or `@differentiable(linear)` function type - /// for the given differentiability kind and parameter indices representing - /// differentiability/linearity parameters. + /// for the given differentiability kind and differentiability/linearity + /// parameter/result indices. CanSILFunctionType getWithDifferentiability(DifferentiabilityKind kind, - IndexSubset *parameterIndices); + IndexSubset *parameterIndices, + IndexSubset *resultIndices); /// Returns the SIL function type stripping differentiability kind and /// differentiability from all parameters. CanSILFunctionType getWithoutDifferentiability(); /// Returns the type of the derivative function for the given parameter - /// indices, result index, derivative function kind, derivative function + /// indices, result indices, derivative function kind, derivative function /// generic signature (optional), and other auxiliary parameters. /// /// Preconditions: /// - Parameters corresponding to parameter indices must conform to /// `Differentiable`. - /// - The result corresponding to the result index must conform to + /// - Results corresponding to result indices must conform to /// `Differentiable`. /// /// Typing rules, given: @@ -4793,14 +4843,8 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode, /// function - this is more direct. It may be possible to implement /// reabstraction thunk derivatives using "reabstraction thunks for /// the original function's derivative", avoiding extra code generation. - /// - /// Caveats: - /// - We may support multiple result indices instead of a single result index - /// eventually. At the SIL level, this enables differentiating wrt multiple - /// function results. At the Swift level, this enables differentiating wrt - /// multiple tuple elements for tuple-returning functions. CanSILFunctionType getAutoDiffDerivativeFunctionType( - IndexSubset *parameterIndices, unsigned resultIndex, + IndexSubset *parameterIndices, IndexSubset *resultIndices, AutoDiffDerivativeFunctionKind kind, Lowering::TypeConverter &TC, LookupConformanceFn lookupConformance, CanGenericSignature derivativeFunctionGenericSignature = nullptr, diff --git a/include/swift/Basic/DiagnosticOptions.h b/include/swift/Basic/DiagnosticOptions.h index 58531d5908641..31e6149412692 100644 --- a/include/swift/Basic/DiagnosticOptions.h +++ b/include/swift/Basic/DiagnosticOptions.h @@ -32,6 +32,8 @@ class DiagnosticOptions { VerifyAndApplyFixes } VerifyMode = NoVerify; + enum FormattingStyle { LLVM, Swift }; + /// Indicates whether to allow diagnostics for \c locations if /// \c VerifyMode is not \c NoVerify. bool VerifyIgnoreUnknown = false; @@ -61,7 +63,7 @@ class DiagnosticOptions { // If set to true, use the more descriptive experimental formatting style for // diagnostics. - bool EnableExperimentalFormatting = false; + FormattingStyle PrintedFormattingStyle = FormattingStyle::LLVM; std::string DiagnosticDocumentationPath = ""; diff --git a/include/swift/Basic/LLVM.h b/include/swift/Basic/LLVM.h index c88b322b0ecd7..df5db366409dd 100644 --- a/include/swift/Basic/LLVM.h +++ b/include/swift/Basic/LLVM.h @@ -36,8 +36,8 @@ namespace llvm { template class SmallPtrSet; #if !defined(swiftCore_EXPORTS) template class SmallVectorImpl; -#endif template class SmallVector; +#endif template class SmallString; template class SmallSetVector; #if !defined(swiftCore_EXPORTS) @@ -86,8 +86,8 @@ namespace swift { using llvm::SmallPtrSetImpl; using llvm::SmallSetVector; using llvm::SmallString; - using llvm::SmallVector; #if !defined(swiftCore_EXPORTS) + using llvm::SmallVector; using llvm::SmallVectorImpl; #endif using llvm::StringLiteral; diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index d193f011a8824..9456b729871b3 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -267,6 +267,10 @@ namespace swift { /// Build the ASTScope tree lazily bool LazyASTScopes = true; + /// Whether to enable the new operator decl and precedencegroup lookup + /// behavior. This is a staging flag, and will be removed in the future. + bool EnableNewOperatorLookup = false; + /// Use Clang function types for computing canonical types. /// If this option is false, the clang function types will still be computed /// but will not be used for checking type equality. @@ -331,6 +335,10 @@ namespace swift { /// Whether to verify the parsed syntax tree and emit related diagnostics. bool VerifySyntaxTree = false; + /// Whether to disable the evaluation of '#if' decls, such that the bodies + /// of active clauses aren't hoisted into the enclosing scope. + bool DisablePoundIfEvaluation = false; + /// Instead of hashing tokens inside of NominalType and ExtensionBodies into /// the interface hash, hash them into per-iterable-decl-context /// fingerprints. Fine-grained dependency types won't dirty every provides @@ -359,7 +367,7 @@ namespace swift { /// Whether to enable a more aggressive mode of incremental dependency /// gathering that never captures cascading edges. - bool EnableExperientalPrivateIntransitiveDependencies = false; + bool DirectIntramoduleDependencies = true; /// Enable verification when every SubstitutionMap is constructed. bool VerifyAllSubstitutionMaps = false; @@ -545,7 +553,10 @@ namespace swift { /// Enable constraint solver support for experimental /// operator protocol designator feature. bool SolverEnableOperatorDesignatedTypes = false; - + + /// Enable experimental support for one-way constraints for the + /// parameters of closures. + bool EnableOneWayClosureParameters = false; }; } // end namespace swift diff --git a/include/swift/Basic/OutputFileMap.h b/include/swift/Basic/OutputFileMap.h index 8f3235c05e247..363288f25b704 100644 --- a/include/swift/Basic/OutputFileMap.h +++ b/include/swift/Basic/OutputFileMap.h @@ -17,7 +17,6 @@ #include "swift/Basic/LLVM.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringSet.h" #include "llvm/Support/Error.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" diff --git a/include/swift/Basic/SimpleDisplay.h b/include/swift/Basic/SimpleDisplay.h index 3a553359091aa..3a31da14654ac 100644 --- a/include/swift/Basic/SimpleDisplay.h +++ b/include/swift/Basic/SimpleDisplay.h @@ -136,6 +136,20 @@ namespace swift { out << "}"; } + template + void simple_display(llvm::raw_ostream &out, + const std::vector &vec) { + out << "{"; + bool first = true; + for (const T &value : vec) { + if (first) first = false; + else out << ", "; + + simple_display(out, value); + } + out << "}"; + } + template void simple_display(llvm::raw_ostream &out, const llvm::PointerUnion &ptrUnion) { diff --git a/include/swift/Basic/SourceManager.h b/include/swift/Basic/SourceManager.h index d05e8c9e66f81..e26e44e78cef9 100644 --- a/include/swift/Basic/SourceManager.h +++ b/include/swift/Basic/SourceManager.h @@ -17,7 +17,6 @@ #include "swift/Basic/SourceLoc.h" #include "clang/Basic/FileManager.h" #include "llvm/ADT/Optional.h" -#include "llvm/ADT/StringMap.h" #include "llvm/Support/SourceMgr.h" #include @@ -206,7 +205,7 @@ class SourceManager { /// /// This respects \c #sourceLocation directives. std::pair - getLineAndColumn(SourceLoc Loc, unsigned BufferID = 0) const { + getPresumedLineAndColumnForLoc(SourceLoc Loc, unsigned BufferID = 0) const { assert(Loc.isValid()); int LineOffset = getLineOffset(Loc); int l, c; @@ -215,14 +214,15 @@ class SourceManager { return { LineOffset + l, c }; } - /// Returns the real line number for a source location. + /// Returns the real line and column for a source location. /// /// If \p BufferID is provided, \p Loc must come from that source buffer. /// /// This does not respect \c #sourceLocation directives. - unsigned getLineNumber(SourceLoc Loc, unsigned BufferID = 0) const { + std::pair + getLineAndColumnInBuffer(SourceLoc Loc, unsigned BufferID = 0) const { assert(Loc.isValid()); - return LLVMSourceMgr.FindLineNumber(Loc.Value, BufferID); + return LLVMSourceMgr.getLineAndColumn(Loc.Value, BufferID); } StringRef getEntireTextForBuffer(unsigned BufferID) const; @@ -268,6 +268,11 @@ class SourceManager { else return 0; } + +public: + bool isLocInVirtualFile(SourceLoc Loc) const { + return getVirtualFile(Loc) != nullptr; + } }; } // end namespace swift diff --git a/include/swift/Basic/Statistics.def b/include/swift/Basic/Statistics.def index 6cc99e356934c..419567fc8bba5 100644 --- a/include/swift/Basic/Statistics.def +++ b/include/swift/Basic/Statistics.def @@ -247,9 +247,6 @@ FRONTEND_STATISTIC(Sema, NamedLazyMemberLoadSuccessCount) /// Number of types deserialized. FRONTEND_STATISTIC(Sema, NumTypesDeserialized) -/// Number of types validated. -FRONTEND_STATISTIC(Sema, NumTypesValidated) - /// Number of lazy iterable declaration contexts left unloaded. FRONTEND_STATISTIC(Sema, NumUnloadedLazyIterableDeclContexts) diff --git a/include/swift/Basic/SupplementaryOutputPaths.h b/include/swift/Basic/SupplementaryOutputPaths.h index d24d94822bafb..c1d0494a95891 100644 --- a/include/swift/Basic/SupplementaryOutputPaths.h +++ b/include/swift/Basic/SupplementaryOutputPaths.h @@ -14,7 +14,6 @@ #define SWIFT_FRONTEND_SUPPLEMENTARYOUTPUTPATHS_H #include "swift/Basic/LLVM.h" -#include "llvm/ADT/Optional.h" #include diff --git a/include/swift/Basic/TypeID.h b/include/swift/Basic/TypeID.h index 49e66bb5457cb..b7a4cc2bbc6ec 100644 --- a/include/swift/Basic/TypeID.h +++ b/include/swift/Basic/TypeID.h @@ -19,9 +19,12 @@ #ifndef SWIFT_BASIC_TYPEID_H #define SWIFT_BASIC_TYPEID_H -#include "llvm/ADT/StringRef.h" +// NOTE: Most of these includes are for CTypeIDZone.def and DefineTypeIDZone.h. +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/TinyPtrVector.h" +#include "llvm/ADT/StringRef.h" #include +#include #include #include diff --git a/include/swift/Basic/UUID.h b/include/swift/Basic/UUID.h index a39202e688db2..1aa508fd6209c 100644 --- a/include/swift/Basic/UUID.h +++ b/include/swift/Basic/UUID.h @@ -21,8 +21,6 @@ #include "swift/Basic/LLVM.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Optional.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringRef.h" #include "llvm/Support/raw_ostream.h" #include diff --git a/include/swift/ClangImporter/ClangImporter.h b/include/swift/ClangImporter/ClangImporter.h index 6cce6c7cf386a..e894dd1855535 100644 --- a/include/swift/ClangImporter/ClangImporter.h +++ b/include/swift/ClangImporter/ClangImporter.h @@ -43,6 +43,12 @@ namespace clang { class Type; class VisibleDeclConsumer; class DeclarationName; + class CompilerInvocation; +namespace tooling { +namespace dependencies { + struct FullDependenciesResult; +} +} } namespace swift { @@ -148,6 +154,14 @@ class ClangImporter final : public ClangModuleLoader { std::string swiftPCHHash = "", DependencyTracker *tracker = nullptr, DWARFImporterDelegate *dwarfImporterDelegate = nullptr); + static std::vector + getClangArguments(ASTContext &ctx, const ClangImporterOptions &importerOpts); + + static std::unique_ptr + createClangInvocation(ClangImporter *importer, + const ClangImporterOptions &importerOpts, + ArrayRef invocationArgStrs, + std::vector *CC1Args = nullptr); ClangImporter(const ClangImporter &) = delete; ClangImporter(ClangImporter &&) = delete; ClangImporter &operator=(const ClangImporter &) = delete; @@ -369,6 +383,10 @@ class ClangImporter final : public ClangModuleLoader { void verifyAllModules() override; + void recordModuleDependencies( + ModuleDependenciesCache &cache, + const clang::tooling::dependencies::FullDependenciesResult &clangDependencies); + Optional getModuleDependencies( StringRef moduleName, ModuleDependenciesCache &cache, InterfaceSubContextDelegate &delegate) override; @@ -455,11 +473,18 @@ class ClangImporter final : public ClangModuleLoader { bool isSerializable(const clang::Type *type, bool checkCanonical) const override; + ArrayRef getExtraClangArgs() const; }; ImportDecl *createImportDecl(ASTContext &Ctx, DeclContext *DC, ClangNode ClangN, ArrayRef Exported); +/// Extract the specified-or-defaulted -module-cache-path that winds up in +/// the clang importer, for reuse as the .swiftmodule cache path when +/// building a ModuleInterfaceLoader. +std::string +getModuleCachePathFromClang(const clang::CompilerInstance &Instance); + } // end namespace swift #endif diff --git a/include/swift/ClangImporter/ClangImporterOptions.h b/include/swift/ClangImporter/ClangImporterOptions.h index 14e593daf88a0..173abc210f560 100644 --- a/include/swift/ClangImporter/ClangImporterOptions.h +++ b/include/swift/ClangImporter/ClangImporterOptions.h @@ -103,6 +103,10 @@ class ClangImporterOptions { /// DWARFImporter delegate. bool DisableSourceImport = false; + /// When set, use ExtraArgs alone to configure clang instance because ExtraArgs + /// contains the full option set. + bool ExtraArgsOnly = false; + /// Return a hash code of any components from these options that should /// contribute to a Swift Bridging PCH hash. llvm::hash_code getPCHHashComponents() const { diff --git a/include/swift/Config.h.in b/include/swift/Config.h.in index ec8030b3d1b03..b4e46a98b7b79 100644 --- a/include/swift/Config.h.in +++ b/include/swift/Config.h.in @@ -4,8 +4,6 @@ #ifndef SWIFT_CONFIG_H #define SWIFT_CONFIG_H -#cmakedefine SWIFT_HAVE_WORKING_STD_REGEX 1 - #cmakedefine HAVE_WAIT4 1 #cmakedefine HAVE_PROC_PID_RUSAGE 1 diff --git a/include/swift/Demangling/Demangle.h b/include/swift/Demangling/Demangle.h index ce3a4b5d439c3..4d809e7268078 100644 --- a/include/swift/Demangling/Demangle.h +++ b/include/swift/Demangling/Demangle.h @@ -42,7 +42,6 @@ std::string genericParameterName(uint64_t depth, uint64_t index); /// Display style options for the demangler. struct DemangleOptions { bool SynthesizeSugarOnTypes = false; - bool DisplayDebuggerGeneratedModule = true; bool QualifyEntities = true; bool DisplayExtensionContexts = true; bool DisplayUnmangledSuffix = true; @@ -57,6 +56,12 @@ struct DemangleOptions { bool ShortenArchetype = false; bool ShowPrivateDiscriminators = true; bool ShowFunctionArgumentTypes = true; + bool DisplayDebuggerGeneratedModule = true; + bool DisplayStdlibModule = true; + bool DisplayObjCModule = true; + /// If this is nonempty, entities in this module name will not be qualified. + llvm::StringRef HidingCurrentModule; + /// A function to render generic parameter names. std::function GenericParameterName = genericParameterName; diff --git a/include/swift/Demangling/DemangleNodes.def b/include/swift/Demangling/DemangleNodes.def index 8321255140d40..5e534c3e901fe 100644 --- a/include/swift/Demangling/DemangleNodes.def +++ b/include/swift/Demangling/DemangleNodes.def @@ -287,5 +287,9 @@ NODE(OpaqueTypeDescriptorAccessorVar) NODE(OpaqueReturnType) CONTEXT_NODE(OpaqueReturnTypeOf) +// Added in Swift 5.3 +NODE(CanonicalSpecializedGenericMetaclass) +NODE(CanonicalSpecializedGenericTypeMetadataAccessFunction) + #undef CONTEXT_NODE #undef NODE diff --git a/include/swift/Demangling/TypeDecoder.h b/include/swift/Demangling/TypeDecoder.h index 8bfc73f4e932d..fb87307e97b34 100644 --- a/include/swift/Demangling/TypeDecoder.h +++ b/include/swift/Demangling/TypeDecoder.h @@ -94,22 +94,13 @@ enum class ImplParameterDifferentiability { NotDifferentiable }; -static inline llvm::Optional -getDifferentiabilityFromString(StringRef string) { - if (string.empty()) - return ImplParameterDifferentiability::DifferentiableOrNotApplicable; - if (string == "@noDerivative") - return ImplParameterDifferentiability::NotDifferentiable; - return None; -} - /// Describe a lowered function parameter, parameterized on the type /// representation. template class ImplFunctionParam { + BuiltType Type; ImplParameterConvention Convention; ImplParameterDifferentiability Differentiability; - BuiltType Type; public: using ConventionType = ImplParameterConvention; @@ -137,9 +128,18 @@ class ImplFunctionParam { return None; } - ImplFunctionParam(ImplParameterConvention convention, - ImplParameterDifferentiability diffKind, BuiltType type) - : Convention(convention), Differentiability(diffKind), Type(type) {} + static llvm::Optional + getDifferentiabilityFromString(StringRef string) { + if (string.empty()) + return DifferentiabilityType::DifferentiableOrNotApplicable; + if (string == "@noDerivative") + return DifferentiabilityType::NotDifferentiable; + return None; + } + + ImplFunctionParam(BuiltType type, ImplParameterConvention convention, + ImplParameterDifferentiability diffKind) + : Type(type), Convention(convention), Differentiability(diffKind) {} ImplParameterConvention getConvention() const { return Convention; } @@ -158,15 +158,22 @@ enum class ImplResultConvention { Autoreleased, }; +enum class ImplResultDifferentiability { + DifferentiableOrNotApplicable, + NotDifferentiable +}; + /// Describe a lowered function result, parameterized on the type /// representation. template class ImplFunctionResult { - ImplResultConvention Convention; BuiltType Type; + ImplResultConvention Convention; + ImplResultDifferentiability Differentiability; public: using ConventionType = ImplResultConvention; + using DifferentiabilityType = ImplResultDifferentiability; static llvm::Optional getConventionFromString(StringRef conventionString) { @@ -184,11 +191,27 @@ class ImplFunctionResult { return None; } - ImplFunctionResult(ImplResultConvention convention, BuiltType type) - : Convention(convention), Type(type) {} + static llvm::Optional + getDifferentiabilityFromString(StringRef string) { + if (string.empty()) + return DifferentiabilityType::DifferentiableOrNotApplicable; + if (string == "@noDerivative") + return DifferentiabilityType::NotDifferentiable; + return None; + } + + ImplFunctionResult( + BuiltType type, ImplResultConvention convention, + ImplResultDifferentiability diffKind = + ImplResultDifferentiability::DifferentiableOrNotApplicable) + : Type(type), Convention(convention), Differentiability(diffKind) {} ImplResultConvention getConvention() const { return Convention; } + ImplResultDifferentiability getDifferentiability() const { + return Differentiability; + } + BuiltType getType() const { return Type; } }; @@ -361,7 +384,7 @@ class TypeDecoder { if (Node->getNumChildren() < 2) return BuiltType(); - SmallVector args; + llvm::SmallVector args; const auto &genericArgs = Node->getChild(1); if (genericArgs->getKind() != NodeKind::TypeList) @@ -474,7 +497,7 @@ class TypeDecoder { return BuiltType(); // Find the protocol list. - SmallVector Protocols; + llvm::SmallVector Protocols; auto TypeList = Node->getChild(0); if (TypeList->getKind() == NodeKind::ProtocolList && TypeList->getNumChildren() >= 1) { @@ -576,7 +599,7 @@ class TypeDecoder { return BuiltType(); bool hasParamFlags = false; - SmallVector, 8> parameters; + llvm::SmallVector, 8> parameters; if (!decodeMangledFunctionInputType(Node->getChild(isThrow ? 1 : 0), parameters, hasParamFlags)) return BuiltType(); @@ -598,9 +621,9 @@ class TypeDecoder { } case NodeKind::ImplFunctionType: { auto calleeConvention = ImplParameterConvention::Direct_Unowned; - SmallVector, 8> parameters; - SmallVector, 8> results; - SmallVector, 8> errorResults; + llvm::SmallVector, 8> parameters; + llvm::SmallVector, 8> results; + llvm::SmallVector, 8> errorResults; ImplFunctionTypeFlags flags; for (unsigned i = 0; i < Node->getNumChildren(); i++) { @@ -640,7 +663,7 @@ class TypeDecoder { if (decodeImplFunctionParam(child, parameters)) return BuiltType(); } else if (child->getKind() == NodeKind::ImplResult) { - if (decodeImplFunctionPart(child, results)) + if (decodeImplFunctionParam(child, results)) return BuiltType(); } else if (child->getKind() == NodeKind::ImplErrorResult) { if (decodeImplFunctionPart(child, errorResults)) @@ -684,7 +707,7 @@ class TypeDecoder { return decodeMangledType(Node->getChild(0)); case NodeKind::Tuple: { - SmallVector elements; + llvm::SmallVector elements; std::string labels; bool variadic = false; for (auto &element : *Node) { @@ -913,13 +936,13 @@ class TypeDecoder { if (!type) return true; - results.emplace_back(*convention, type); + results.emplace_back(type, *convention); return false; } - bool decodeImplFunctionParam( - Demangle::NodePointer node, - llvm::SmallVectorImpl> &results) { + template + bool decodeImplFunctionParam(Demangle::NodePointer node, + llvm::SmallVectorImpl &results) { // Children: `convention, differentiability?, type` if (node->getNumChildren() != 2 && node->getNumChildren() != 3) return true; @@ -931,28 +954,26 @@ class TypeDecoder { return true; StringRef conventionString = conventionNode->getText(); - auto convention = - ImplFunctionParam::getConventionFromString(conventionString); + auto convention = T::getConventionFromString(conventionString); if (!convention) return true; BuiltType type = decodeMangledType(typeNode); if (!type) return true; - auto diffKind = - ImplParameterDifferentiability::DifferentiableOrNotApplicable; + auto diffKind = T::DifferentiabilityType::DifferentiableOrNotApplicable; if (node->getNumChildren() == 3) { auto diffKindNode = node->getChild(1); if (diffKindNode->getKind() != Node::Kind::ImplDifferentiability) return true; auto optDiffKind = - getDifferentiabilityFromString(diffKindNode->getText()); + T::getDifferentiabilityFromString(diffKindNode->getText()); if (!optDiffKind) return true; diffKind = *optDiffKind; } - results.emplace_back(*convention, diffKind, type); + results.emplace_back(type, *convention, diffKind); return false; } diff --git a/include/swift/Driver/Action.h b/include/swift/Driver/Action.h index 3f4e5c4edec14..02801d8aece66 100644 --- a/include/swift/Driver/Action.h +++ b/include/swift/Driver/Action.h @@ -17,7 +17,6 @@ #include "swift/Basic/LLVM.h" #include "swift/Driver/Util.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/TinyPtrVector.h" #include "llvm/Support/Chrono.h" diff --git a/include/swift/Driver/Compilation.h b/include/swift/Driver/Compilation.h index 57baeb81db99e..840681c69e868 100644 --- a/include/swift/Driver/Compilation.h +++ b/include/swift/Driver/Compilation.h @@ -26,7 +26,6 @@ #include "swift/Driver/Driver.h" #include "swift/Driver/Job.h" #include "swift/Driver/Util.h" -#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Chrono.h" diff --git a/include/swift/Driver/Driver.h b/include/swift/Driver/Driver.h index 9723f4527ced4..5e055359d6346 100644 --- a/include/swift/Driver/Driver.h +++ b/include/swift/Driver/Driver.h @@ -25,7 +25,6 @@ #include "swift/Basic/Sanitizers.h" #include "swift/Driver/Util.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include diff --git a/include/swift/Driver/FineGrainedDependencyDriverGraph.h b/include/swift/Driver/FineGrainedDependencyDriverGraph.h index 1f04df6ec93ac..16f9a70dea984 100644 --- a/include/swift/Driver/FineGrainedDependencyDriverGraph.h +++ b/include/swift/Driver/FineGrainedDependencyDriverGraph.h @@ -19,12 +19,8 @@ #include "swift/Basic/OptionSet.h" #include "swift/Driver/Job.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/StringSet.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Support/Path.h" #include "llvm/Support/PointerLikeTypeTraits.h" diff --git a/include/swift/Driver/FrontendUtil.h b/include/swift/Driver/FrontendUtil.h index 78e307cd47000..cfa46e017a67b 100644 --- a/include/swift/Driver/FrontendUtil.h +++ b/include/swift/Driver/FrontendUtil.h @@ -33,6 +33,9 @@ namespace driver { /// \param Action Called with the list of frontend arguments if there were no /// errors in processing \p ArgList. This is a callback rather than a return /// value to avoid copying the arguments more than necessary. +/// \param ForceNoOutputs If true, override the output mode to "-typecheck" and +/// produce no outputs. For example, this disables "-emit-module" and "-c" and +/// prevents the creation of temporary files. /// /// \returns True on error, or if \p Action returns true. /// @@ -40,7 +43,8 @@ namespace driver { /// suitable for use in REPL or immediate modes. bool getSingleFrontendInvocationFromDriverArguments( ArrayRef ArgList, DiagnosticEngine &Diags, - llvm::function_ref FrontendArgs)> Action); + llvm::function_ref FrontendArgs)> Action, + bool ForceNoOutputs = false); } // end namespace driver } // end namespace swift diff --git a/include/swift/Driver/Job.h b/include/swift/Driver/Job.h index e57952545bb64..52ba51aafa1fe 100644 --- a/include/swift/Driver/Job.h +++ b/include/swift/Driver/Job.h @@ -20,7 +20,6 @@ #include "swift/Driver/Action.h" #include "swift/Driver/Util.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" diff --git a/include/swift/Frontend/DiagnosticVerifier.h b/include/swift/Frontend/DiagnosticVerifier.h index 5671106996f6e..dcd62914e5e28 100644 --- a/include/swift/Frontend/DiagnosticVerifier.h +++ b/include/swift/Frontend/DiagnosticVerifier.h @@ -30,10 +30,8 @@ class SourceFile; // MARK: - DependencyVerifier -bool verifyDependencies(SourceManager &SM, const DependencyTracker &DT, - ArrayRef SFs); -bool verifyDependencies(SourceManager &SM, const DependencyTracker &DT, - ArrayRef SFs); +bool verifyDependencies(SourceManager &SM, ArrayRef SFs); +bool verifyDependencies(SourceManager &SM, ArrayRef SFs); // MARK: - DiagnosticVerifier struct ExpectedFixIt; diff --git a/include/swift/Frontend/Frontend.h b/include/swift/Frontend/Frontend.h index 33d62e639499f..f8cad378fc6ae 100644 --- a/include/swift/Frontend/Frontend.h +++ b/include/swift/Frontend/Frontend.h @@ -441,8 +441,9 @@ class CompilerInstance { std::vector InputSourceCodeBufferIDs; /// Contains \c MemoryBuffers for partial serialized module files and - /// corresponding partial serialized module documentation files. - std::vector PartialModules; + /// corresponding partial serialized module documentation files. This is + /// \c mutable as it is consumed by \c loadPartialModulesAndImplicitImports. + mutable std::vector PartialModules; enum : unsigned { NO_SUCH_BUFFER = ~0U }; unsigned MainBufferID = NO_SUCH_BUFFER; @@ -451,14 +452,6 @@ class CompilerInstance { /// considered primaries. llvm::SetVector PrimaryBufferIDs; - /// Identifies the set of SourceFiles that are considered primaries. An - /// invariant is that any SourceFile in this set with an associated - /// buffer will also have its buffer ID in PrimaryBufferIDs. - std::vector PrimarySourceFiles; - - /// The file that has been registered for code completion. - NullablePtr CodeCompletionFile; - /// Return whether there is an entry in PrimaryInputs for buffer \p BufID. bool isPrimaryInput(unsigned BufID) const { return PrimaryBufferIDs.count(BufID) != 0; @@ -468,7 +461,7 @@ class CompilerInstance { /// If \p BufID is already in the set, do nothing. void recordPrimaryInputBuffer(unsigned BufID); - bool isWholeModuleCompilation() { return PrimaryBufferIDs.empty(); } + bool isWholeModuleCompilation() const { return PrimaryBufferIDs.empty(); } public: // Out of line to avoid having to import SILModule.h. @@ -514,8 +507,13 @@ class CompilerInstance { UnifiedStatsReporter *getStatsReporter() const { return Stats.get(); } + /// Retrieve the main module containing the files being compiled. ModuleDecl *getMainModule() const; + /// Replace the current main module with a new one. This is used for top-level + /// cached code completion. + void setMainModule(ModuleDecl *newMod); + MemoryBufferSerializedModuleLoader * getMemoryBufferSerializedModuleLoader() const { return MemoryBufferLoader; @@ -536,7 +534,7 @@ class CompilerInstance { /// Gets the set of SourceFiles which are the primary inputs for this /// CompilerInstance. ArrayRef getPrimarySourceFiles() const { - return PrimarySourceFiles; + return getMainModule()->getPrimarySourceFiles(); } /// Gets the SourceFile which is the primary input for this CompilerInstance. @@ -546,11 +544,12 @@ class CompilerInstance { /// FIXME: This should be removed eventually, once there are no longer any /// codepaths that rely on a single primary file. SourceFile *getPrimarySourceFile() const { - if (PrimarySourceFiles.empty()) { + auto primaries = getPrimarySourceFiles(); + if (primaries.empty()) { return nullptr; } else { - assert(PrimarySourceFiles.size() == 1); - return *PrimarySourceFiles.begin(); + assert(primaries.size() == 1); + return *primaries.begin(); } } @@ -561,12 +560,7 @@ class CompilerInstance { /// If a code completion buffer has been set, returns the corresponding source /// file. - NullablePtr getCodeCompletionFile() { return CodeCompletionFile; } - - /// Set a new file that we're performing code completion on. - void setCodeCompletionFile(SourceFile *file) { - CodeCompletionFile = file; - } + SourceFile *getCodeCompletionFile() const; private: /// Set up the file system by loading and validating all VFS overlay YAML @@ -622,10 +616,6 @@ class CompilerInstance { /// Parses and type-checks all input files. void performSema(); - /// Parses the input file but does no type-checking or module imports. - void performParseOnly(bool EvaluateConditionals = false, - bool CanDelayBodies = true); - /// Parses and performs import resolution on all input files. /// /// This is similar to a parse-only invocation, but module imports will also @@ -638,26 +628,35 @@ class CompilerInstance { bool performSILProcessing(SILModule *silModule); private: - SourceFile * - createSourceFileForMainModule(SourceFileKind FileKind, - Optional BufferID, - SourceFile::ParsingOptions options = {}); + /// Creates a new source file for the main module. + SourceFile *createSourceFileForMainModule(ModuleDecl *mod, + SourceFileKind FileKind, + Optional BufferID) const; + + /// Creates all the files to be added to the main module, appending them to + /// \p files. If a loading error occurs, returns \c true. + bool createFilesForMainModule(ModuleDecl *mod, + SmallVectorImpl &files) const; public: void freeASTContext(); + /// If an implicit standard library import is expected, loads the standard + /// library, returning \c false if we should continue, i.e. no error. + bool loadStdlibIfNeeded(); + private: - /// Load stdlib & return true if should continue, i.e. no error - bool loadStdlib(); + /// Compute the parsing options for a source file in the main module. + SourceFile::ParsingOptions getSourceFileParsingOptions(bool forPrimary) const; /// Retrieve a description of which modules should be implicitly imported. ImplicitImportInfo getImplicitImportInfo() const; - void performSemaUpTo(SourceFile::ASTStage_t LimitStage, - SourceFile::ParsingOptions POpts = {}); - - /// Return true if had load error - bool loadPartialModulesAndImplicitImports(); + /// For any serialized AST inputs, loads them in as partial module files, + /// appending them to \p partialModules. If a loading error occurs, returns + /// \c true. + bool loadPartialModulesAndImplicitImports( + ModuleDecl *mod, SmallVectorImpl &partialModules) const; void forEachFileToTypeCheck(llvm::function_ref fn); diff --git a/include/swift/Frontend/FrontendInputsAndOutputs.h b/include/swift/Frontend/FrontendInputsAndOutputs.h index ccc699e211e30..76f5ef125bc14 100644 --- a/include/swift/Frontend/FrontendInputsAndOutputs.h +++ b/include/swift/Frontend/FrontendInputsAndOutputs.h @@ -17,7 +17,6 @@ #include "swift/Basic/SupplementaryOutputPaths.h" #include "swift/Frontend/InputFile.h" #include "llvm/ADT/Hashing.h" -#include "llvm/ADT/MapVector.h" #include #include diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h index 710efc42f9368..201202cd983a1 100644 --- a/include/swift/Frontend/FrontendOptions.h +++ b/include/swift/Frontend/FrontendOptions.h @@ -258,6 +258,10 @@ class FrontendOptions { /// By default, we include ImplicitObjCHeaderPath directly. llvm::Optional BridgingHeaderDirForPrint; + /// Disable implicitly built Swift modules because they are explicitly + /// built and given to the compiler invocation. + bool DisableImplicitModules = false; + /// The different modes for validating TBD against the LLVM IR. enum class TBDValidationMode { Default, ///< Do the default validation for the current platform. diff --git a/include/swift/Frontend/InputFile.h b/include/swift/Frontend/InputFile.h index 52678c9a2e951..bd9e24808f60e 100644 --- a/include/swift/Frontend/InputFile.h +++ b/include/swift/Frontend/InputFile.h @@ -17,7 +17,6 @@ #include "swift/Basic/SupplementaryOutputPaths.h" #include "llvm/Support/MemoryBuffer.h" #include -#include namespace swift { diff --git a/include/swift/Frontend/ModuleInterfaceLoader.h b/include/swift/Frontend/ModuleInterfaceLoader.h index 2a793922a1605..22c183beb2c69 100644 --- a/include/swift/Frontend/ModuleInterfaceLoader.h +++ b/include/swift/Frontend/ModuleInterfaceLoader.h @@ -127,6 +127,49 @@ class LangOptions; class SearchPathOptions; class CompilerInvocation; +/// A ModuleLoader that loads explicitly built Swift modules specified via +/// -swift-module-file +class ExplicitSwiftModuleLoader: public SerializedModuleLoaderBase { + explicit ExplicitSwiftModuleLoader(ASTContext &ctx, DependencyTracker *tracker, + ModuleLoadingMode loadMode, + bool IgnoreSwiftSourceInfoFile); + std::error_code findModuleFilesInDirectory( + AccessPathElem ModuleID, + const SerializedModuleBaseName &BaseName, + SmallVectorImpl *ModuleInterfacePath, + std::unique_ptr *ModuleBuffer, + std::unique_ptr *ModuleDocBuffer, + std::unique_ptr *ModuleSourceInfoBuffer) override; + + bool isCached(StringRef DepPath) override { return false; }; + + struct Implementation; + Implementation &Impl; +public: + static std::unique_ptr + create(ASTContext &ctx, + DependencyTracker *tracker, ModuleLoadingMode loadMode, + ArrayRef ExplicitModulePaths, + bool IgnoreSwiftSourceInfoFile); + + /// Append visible module names to \p names. Note that names are possibly + /// duplicated, and not guaranteed to be ordered in any way. + void collectVisibleTopLevelModuleNames( + SmallVectorImpl &names) const override; + ~ExplicitSwiftModuleLoader(); +}; + +struct ModuleInterfaceLoaderOptions { + bool remarkOnRebuildFromInterface = false; + bool disableInterfaceLock = false; + bool disableImplicitSwiftModule = false; + ModuleInterfaceLoaderOptions(const FrontendOptions &Opts): + remarkOnRebuildFromInterface(Opts.RemarkOnRebuildFromModuleInterface), + disableInterfaceLock(Opts.DisableInterfaceFileLock), + disableImplicitSwiftModule(Opts.DisableImplicitModules) {} + ModuleInterfaceLoaderOptions() = default; +}; + /// A ModuleLoader that runs a subordinate \c CompilerInvocation and /// \c CompilerInstance to convert .swiftinterface files to .swiftmodule /// files on the fly, caching the resulting .swiftmodules in the module cache @@ -137,21 +180,17 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase { ASTContext &ctx, StringRef cacheDir, StringRef prebuiltCacheDir, DependencyTracker *tracker, ModuleLoadingMode loadMode, ArrayRef PreferInterfaceForModules, - bool RemarkOnRebuildFromInterface, bool IgnoreSwiftSourceInfoFile, - bool DisableInterfaceFileLock) + bool IgnoreSwiftSourceInfoFile, ModuleInterfaceLoaderOptions Opts) : SerializedModuleLoaderBase(ctx, tracker, loadMode, IgnoreSwiftSourceInfoFile), CacheDir(cacheDir), PrebuiltCacheDir(prebuiltCacheDir), - RemarkOnRebuildFromInterface(RemarkOnRebuildFromInterface), - DisableInterfaceFileLock(DisableInterfaceFileLock), - PreferInterfaceForModules(PreferInterfaceForModules) - {} + PreferInterfaceForModules(PreferInterfaceForModules), + Opts(Opts) {} std::string CacheDir; std::string PrebuiltCacheDir; - bool RemarkOnRebuildFromInterface; - bool DisableInterfaceFileLock; ArrayRef PreferInterfaceForModules; + ModuleInterfaceLoaderOptions Opts; std::error_code findModuleFilesInDirectory( AccessPathElem ModuleID, @@ -168,16 +207,14 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase { create(ASTContext &ctx, StringRef cacheDir, StringRef prebuiltCacheDir, DependencyTracker *tracker, ModuleLoadingMode loadMode, ArrayRef PreferInterfaceForModules = {}, - bool RemarkOnRebuildFromInterface = false, - bool IgnoreSwiftSourceInfoFile = false, - bool DisableInterfaceFileLock = false) { + ModuleInterfaceLoaderOptions Opts = ModuleInterfaceLoaderOptions(), + bool IgnoreSwiftSourceInfoFile = false) { return std::unique_ptr( new ModuleInterfaceLoader(ctx, cacheDir, prebuiltCacheDir, tracker, loadMode, PreferInterfaceForModules, - RemarkOnRebuildFromInterface, IgnoreSwiftSourceInfoFile, - DisableInterfaceFileLock)); + Opts)); } /// Append visible module names to \p names. Note that names are possibly @@ -192,18 +229,13 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase { static bool buildSwiftModuleFromSwiftInterface( SourceManager &SourceMgr, DiagnosticEngine &Diags, const SearchPathOptions &SearchPathOpts, const LangOptions &LangOpts, + const ClangImporterOptions &ClangOpts, StringRef CacheDir, StringRef PrebuiltCacheDir, StringRef ModuleName, StringRef InPath, StringRef OutPath, bool SerializeDependencyHashes, bool TrackSystemDependencies, - bool RemarkOnRebuildFromInterface, bool DisableInterfaceFileLock); + ModuleInterfaceLoaderOptions Opts); }; -/// Extract the specified-or-defaulted -module-cache-path that winds up in -/// the clang importer, for reuse as the .swiftmodule cache path when -/// building a ModuleInterfaceLoader. -std::string -getModuleCachePathFromClang(const clang::CompilerInstance &Instance); - struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate { private: SourceManager &SM; @@ -237,14 +269,13 @@ struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate { DiagnosticEngine &Diags, const SearchPathOptions &searchPathOpts, const LangOptions &langOpts, + ModuleInterfaceLoaderOptions LoaderOpts, ClangModuleLoader *clangImporter, bool buildModuleCacheDirIfAbsent, StringRef moduleCachePath, StringRef prebuiltCachePath, bool serializeDependencyHashes, - bool trackSystemDependencies, - bool remarkOnRebuildFromInterface, - bool disableInterfaceFileLock); + bool trackSystemDependencies); bool runInSubContext(StringRef moduleName, StringRef interfacePath, StringRef outputPath, @@ -264,6 +295,7 @@ struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate { llvm::SmallString<256> &OutPath, StringRef &CacheHash); std::string getCacheHash(StringRef useInterfacePath); + void addExtraClangArg(StringRef Arg); }; } diff --git a/include/swift/Frontend/PrintingDiagnosticConsumer.h b/include/swift/Frontend/PrintingDiagnosticConsumer.h index a4720ce5c6f51..cbbca307f6297 100644 --- a/include/swift/Frontend/PrintingDiagnosticConsumer.h +++ b/include/swift/Frontend/PrintingDiagnosticConsumer.h @@ -18,8 +18,9 @@ #ifndef SWIFT_PRINTINGDIAGNOSTICCONSUMER_H #define SWIFT_PRINTINGDIAGNOSTICCONSUMER_H -#include "swift/Basic/LLVM.h" #include "swift/AST/DiagnosticConsumer.h" +#include "swift/Basic/DiagnosticOptions.h" +#include "swift/Basic/LLVM.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Process.h" @@ -33,7 +34,8 @@ class PrintingDiagnosticConsumer : public DiagnosticConsumer { bool ForceColors = false; bool PrintEducationalNotes = false; bool DidErrorOccur = false; - bool ExperimentalFormattingEnabled = false; + DiagnosticOptions::FormattingStyle FormattingStyle = + DiagnosticOptions::FormattingStyle::LLVM; // The current snippet used to display an error/warning/remark and the notes // implicitly associated with it. Uses `std::unique_ptr` so that // `AnnotatedSourceSnippet` can be forward declared. @@ -65,7 +67,9 @@ class PrintingDiagnosticConsumer : public DiagnosticConsumer { PrintEducationalNotes = ShouldPrint; } - void enableExperimentalFormatting() { ExperimentalFormattingEnabled = true; } + void setFormattingStyle(DiagnosticOptions::FormattingStyle style) { + FormattingStyle = style; + } bool didErrorOccur() { return DidErrorOccur; diff --git a/include/swift/IDE/CommentConversion.h b/include/swift/IDE/CommentConversion.h index d2703a03097fb..50c9ce71a68ad 100644 --- a/include/swift/IDE/CommentConversion.h +++ b/include/swift/IDE/CommentConversion.h @@ -14,6 +14,7 @@ #define SWIFT_IDE_COMMENT_CONVERSION_H #include "swift/Basic/LLVM.h" +#include "swift/AST/TypeOrExtensionDecl.h" #include #include @@ -27,7 +28,9 @@ namespace ide { /// in Clang-like XML format. /// /// \returns true if the declaration has a documentation comment. -bool getDocumentationCommentAsXML(const Decl *D, raw_ostream &OS); +bool getDocumentationCommentAsXML( + const Decl *D, raw_ostream &OS, + TypeOrExtensionDecl SynthesizedTarget = TypeOrExtensionDecl()); /// If the declaration has a documentation comment and a localization key, /// print it into the given output stream and return true. Else, return false. diff --git a/include/swift/IDE/CompletionInstance.h b/include/swift/IDE/CompletionInstance.h index 8eb345fee94da..51687b974b9c0 100644 --- a/include/swift/IDE/CompletionInstance.h +++ b/include/swift/IDE/CompletionInstance.h @@ -16,7 +16,6 @@ #include "swift/Frontend/Frontend.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Chrono.h" #include "llvm/Support/MemoryBuffer.h" @@ -44,7 +43,6 @@ class CompletionInstance { std::mutex mtx; std::unique_ptr CachedCI; - ModuleDecl *CurrentModule = nullptr; llvm::hash_code CachedArgHash; llvm::sys::TimePoint<> DependencyCheckedTimestamp; llvm::StringMap InMemoryDependencyHash; diff --git a/include/swift/IDE/DigesterEnums.def b/include/swift/IDE/DigesterEnums.def index d00a337f4eb21..415db666c919d 100644 --- a/include/swift/IDE/DigesterEnums.def +++ b/include/swift/IDE/DigesterEnums.def @@ -132,6 +132,7 @@ KEY_BOOL(HasStorage, hasStorage) KEY_BOOL(ReqNewWitnessTableEntry, reqNewWitnessTableEntry) KEY_BOOL(IsABIPlaceholder, isABIPlaceholder) KEY_BOOL(IsExternal, isExternal) +KEY_BOOL(IsEnumExhaustive, isEnumExhaustive) KEY_BOOL(HasMissingDesignatedInitializers, hasMissingDesignatedInitializers) KEY_BOOL(InheritsConvenienceInitializers, inheritsConvenienceInitializers) diff --git a/include/swift/IDE/SourceEntityWalker.h b/include/swift/IDE/SourceEntityWalker.h index 08d7e1580fe4b..1a6facca4d74a 100644 --- a/include/swift/IDE/SourceEntityWalker.h +++ b/include/swift/IDE/SourceEntityWalker.h @@ -17,7 +17,6 @@ #include "swift/Basic/LLVM.h" #include "swift/Basic/SourceLoc.h" #include "llvm/ADT/PointerUnion.h" -#include namespace clang { class Module; diff --git a/include/swift/IRGen/Linking.h b/include/swift/IRGen/Linking.h index acfa09b4b9cf7..fac7f4510c30a 100644 --- a/include/swift/IRGen/Linking.h +++ b/include/swift/IRGen/Linking.h @@ -193,7 +193,7 @@ class LinkEntity { /// The nominal type descriptor for a nominal type. /// The pointer is a NominalTypeDecl*. NominalTypeDescriptor, - + /// The descriptor for an opaque type. /// The pointer is an OpaqueTypeDecl*. OpaqueTypeDescriptor, @@ -295,12 +295,12 @@ class LinkEntity { /// The descriptor for an extension. /// The pointer is an ExtensionDecl*. ExtensionDescriptor, - + /// The descriptor for a runtime-anonymous context. /// The pointer is the DeclContext* of a child of the context that should /// be considered private. AnonymousDescriptor, - + /// A SIL global variable. The pointer is a SILGlobalVariable*. SILGlobalVariable, @@ -384,6 +384,15 @@ class LinkEntity { /// A global function pointer for dynamically replaceable functions. DynamicallyReplaceableFunctionVariable, + + /// A reference to a metaclass-stub for a statically specialized generic + /// class. + /// The pointer is a canonical TypeBase*. + CanonicalSpecializedGenericSwiftMetaclassStub, + + /// An access function for prespecialized type metadata. + /// The pointer is a canonical TypeBase*. + CanonicalSpecializedGenericTypeMetadataAccessFunction, }; friend struct llvm::DenseMapInfo; @@ -1020,6 +1029,22 @@ class LinkEntity { return entity; } + static LinkEntity + forSpecializedGenericSwiftMetaclassStub(CanType concreteType) { + LinkEntity entity; + entity.setForType(Kind::CanonicalSpecializedGenericSwiftMetaclassStub, + concreteType); + return entity; + } + + static LinkEntity + forPrespecializedTypeMetadataAccessFunction(CanType theType) { + LinkEntity entity; + entity.setForType( + Kind::CanonicalSpecializedGenericTypeMetadataAccessFunction, theType); + return entity; + } + void mangle(llvm::raw_ostream &out) const; void mangle(SmallVectorImpl &buffer) const; std::string mangleAsString() const; diff --git a/include/swift/Index/IndexSymbol.h b/include/swift/Index/IndexSymbol.h index c086e2a4ac283..338c906a960ae 100644 --- a/include/swift/Index/IndexSymbol.h +++ b/include/swift/Index/IndexSymbol.h @@ -15,7 +15,6 @@ #include "swift/Basic/LLVM.h" #include "clang/Index/IndexSymbol.h" -#include "llvm/ADT/SmallString.h" namespace swift { class Decl; diff --git a/include/swift/Migrator/FixitApplyDiagnosticConsumer.h b/include/swift/Migrator/FixitApplyDiagnosticConsumer.h index 4db9bb78ddfba..4937a881b827d 100644 --- a/include/swift/Migrator/FixitApplyDiagnosticConsumer.h +++ b/include/swift/Migrator/FixitApplyDiagnosticConsumer.h @@ -22,7 +22,7 @@ #include "swift/Migrator/Migrator.h" #include "swift/Migrator/Replacement.h" #include "clang/Rewrite/Core/RewriteBuffer.h" -#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/SmallSet.h" namespace swift { diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td index c8168fde7d545..42b4e5db2974c 100644 --- a/include/swift/Option/FrontendOptions.td +++ b/include/swift/Option/FrontendOptions.td @@ -131,10 +131,6 @@ def enable_cross_import_overlays : Flag<["-"], "enable-cross-import-overlays">, def disable_cross_import_overlays : Flag<["-"], "disable-cross-import-overlays">, HelpText<"Do not automatically import declared cross-import overlays.">; -def enable_experimental_diagnostic_formatting : - Flag<["-"], "enable-experimental-diagnostic-formatting">, - HelpText<"Enable experimental diagnostic formatting features.">; - def diagnostic_documentation_path : Separate<["-"], "diagnostic-documentation-path">, MetaVarName<"">, HelpText<"Path to diagnostic documentation resources">; @@ -218,6 +214,12 @@ def disable_objc_attr_requires_foundation_module : def enable_resilience : Flag<["-"], "enable-resilience">, HelpText<"Deprecated, use -enable-library-evolution instead">; +def disable_implicit_swift_modules: Flag<["-"], "disable-implicit-swift-modules">, + HelpText<"Disable building Swift modules explicitly by the compiler">; + +def swift_module_file + : Separate<["-"], "swift-module-file">, MetaVarName<"">, + HelpText<"Specify Swift module explicitly built from textual interface">; } @@ -483,6 +485,14 @@ def disable_invalid_ephemeralness_as_error : def switch_checking_invocation_threshold_EQ : Joined<["-"], "switch-checking-invocation-threshold=">; +def enable_new_operator_lookup : + Flag<["-"], "enable-new-operator-lookup">, + HelpText<"Enable the new operator decl and precedencegroup lookup behavior">; + +def disable_new_operator_lookup : + Flag<["-"], "disable-new-operator-lookup">, + HelpText<"Disable the new operator decl and precedencegroup lookup behavior">; + def enable_source_import : Flag<["-"], "enable-source-import">, HelpText<"Enable importing of Swift source files">; @@ -632,6 +642,10 @@ def experimental_print_full_convention : HelpText<"When emitting a module interface, emit additional @convention " "arguments, regardless of whether they were written in the source">; +def experimental_one_way_closure_params : + Flag<["-"], "experimental-one-way-closure-params">, + HelpText<"Enable experimental support for one-way closure parameters">; + def prebuilt_module_cache_path : Separate<["-"], "prebuilt-module-cache-path">, HelpText<"Directory of prebuilt modules for loading module interfaces">; @@ -708,4 +722,6 @@ def target_sdk_version : Separate<["-"], "target-sdk-version">, def target_variant_sdk_version : Separate<["-"], "target-variant-sdk-version">, HelpText<"The version of target variant SDK used for compilation">; +def extra_clang_options_only : Flag<["-"], "only-use-extra-clang-opts">, + HelpText<"Options passed via -Xcc are sufficient for Clang configuration">; } // end let Flags = [FrontendOption, NoDriverOption, HelpHidden] diff --git a/include/swift/Option/Options.h b/include/swift/Option/Options.h index 2ecc402f77659..9307d74ab0f56 100644 --- a/include/swift/Option/Options.h +++ b/include/swift/Option/Options.h @@ -36,6 +36,7 @@ namespace options { SwiftIndentOption = (1 << 11), ArgumentIsPath = (1 << 12), ModuleInterfaceOption = (1 << 13), + SupplementaryOutput = (1 << 14), }; enum ID { diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index a430124cc7f27..edaf19bdc3559 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -51,6 +51,10 @@ def ArgumentIsPath : OptionFlag; // and read/parsed from there when reconstituting a .swiftmodule from it. def ModuleInterfaceOption : OptionFlag; +// The option causes the output of a supplementary output, or is the path option +// for a supplementary output. E.g., `-emit-module` and `-emit-module-path`. +def SupplementaryOutput : OptionFlag; + ///////// // Options @@ -314,21 +318,24 @@ def profile_stats_entities: Flag<["-"], "profile-stats-entities">, HelpText<"Profile changes to stats in -stats-output-dir, subdivided by source entity">; def emit_dependencies : Flag<["-"], "emit-dependencies">, - Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>, + Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild, + SupplementaryOutput]>, HelpText<"Emit basic Make-compatible dependencies files">; def track_system_dependencies : Flag<["-"], "track-system-dependencies">, Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>, HelpText<"Track system dependencies while emitting Make-style dependencies">; def emit_loaded_module_trace : Flag<["-"], "emit-loaded-module-trace">, - Flags<[FrontendOption, NoInteractiveOption]>, + Flags<[FrontendOption, NoInteractiveOption, SupplementaryOutput]>, HelpText<"Emit a JSON file containing information about what modules were loaded">; def emit_loaded_module_trace_path : Separate<["-"], "emit-loaded-module-trace-path">, - Flags<[FrontendOption, NoInteractiveOption, ArgumentIsPath]>, + Flags<[FrontendOption, NoInteractiveOption, ArgumentIsPath, + SupplementaryOutput]>, HelpText<"Emit the loaded module trace JSON to ">, MetaVarName<"">; def emit_loaded_module_trace_path_EQ : Joined<["-"], "emit-loaded-module-trace-path=">, - Flags<[FrontendOption, NoInteractiveOption, ArgumentIsPath]>, + Flags<[FrontendOption, NoInteractiveOption, ArgumentIsPath, + SupplementaryOutput]>, Alias; def emit_cross_import_remarks : Flag<["-"], "Rcross-import">, Flags<[FrontendOption, DoesNotAffectIncrementalBuild]>, @@ -336,27 +343,32 @@ def emit_cross_import_remarks : Flag<["-"], "Rcross-import">, def emit_tbd : Flag<["-"], "emit-tbd">, HelpText<"Emit a TBD file">, - Flags<[FrontendOption, NoInteractiveOption]>; + Flags<[FrontendOption, NoInteractiveOption, SupplementaryOutput]>; def emit_tbd_path : Separate<["-"], "emit-tbd-path">, - Flags<[FrontendOption, NoInteractiveOption, ArgumentIsPath]>, + Flags<[FrontendOption, NoInteractiveOption, ArgumentIsPath, + SupplementaryOutput]>, HelpText<"Emit the TBD file to ">, MetaVarName<"">; def emit_tbd_path_EQ : Joined<["-"], "emit-tbd-path=">, - Flags<[FrontendOption, NoInteractiveOption, ArgumentIsPath]>, + Flags<[FrontendOption, NoInteractiveOption, ArgumentIsPath, + SupplementaryOutput]>, Alias; def embed_tbd_for_module : Separate<["-"], "embed-tbd-for-module">, Flags<[FrontendOption]>, HelpText<"Embed symbols from the module in the emitted tbd file">; def serialize_diagnostics : Flag<["-"], "serialize-diagnostics">, - Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>, + Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild, + SupplementaryOutput]>, HelpText<"Serialize diagnostics in a binary format">; def serialize_diagnostics_path : Separate<["-"], "serialize-diagnostics-path">, - Flags<[FrontendOption, NoBatchOption, DoesNotAffectIncrementalBuild, ArgumentIsPath]>, + Flags<[FrontendOption, NoBatchOption, DoesNotAffectIncrementalBuild, + ArgumentIsPath, SupplementaryOutput]>, HelpText<"Emit a serialized diagnostics file to ">, MetaVarName<"">; def serialize_diagnostics_path_EQ: Joined<["-"], "serialize-diagnostics-path=">, - Flags<[FrontendOption, NoBatchOption, DoesNotAffectIncrementalBuild, ArgumentIsPath]>, + Flags<[FrontendOption, NoBatchOption, DoesNotAffectIncrementalBuild, + ArgumentIsPath, SupplementaryOutput]>, Alias; def color_diagnostics : Flag<["-"], "color-diagnostics">, Flags<[FrontendOption, DoesNotAffectIncrementalBuild]>, @@ -370,6 +382,13 @@ def debug_diagnostic_names : Flag<["-"], "debug-diagnostic-names">, def print_educational_notes : Flag<["-"], "print-educational-notes">, Flags<[FrontendOption, DoesNotAffectIncrementalBuild]>, HelpText<"Include educational notes in printed diagnostic output, if available">; +def diagnostic_style : Separate<["-"], "diagnostic-style">, + Flags<[FrontendOption, DoesNotAffectIncrementalBuild]>, + MetaVarName<"