Commit Graph

489 Commits

Author SHA1 Message Date
Alex Lorenz
ba8d4d7801 [cxx-interop] compilations that do not enable C++ interoperability should not be able to import modules that do enable C++ interoperability by default
A supplemental hidden frontend option allows advanced users to opt-out of this requirement.

Fixes https://github.com/apple/swift/issues/65833
Fixes https://github.com/apple/swift/issues/65832
2023-06-09 15:38:16 -07:00
Ellie Shin
2941051fe2 Merge pull request #65481 from apple/es-pkg-import
Limit loading error when importing a module built from interface with package-name
2023-04-28 12:55:07 -07:00
Ellie Shin
e9f847d414 Merge pull request #65336 from apple/es-private
Print package-name in .private.swiftinterface only for better abstraction
2023-04-27 20:07:12 -07:00
Ellie Shin
ceb2884183 Currently it errors when loading a module built from interface if it has package-name.
This disallows building an interface file that imports such module which should be allowed
since interface does not contain package symbols unless usableFromInline or inlinable.
This change limits erroring only when building a .swift file.

Resolves rdar://108633068
2023-04-27 16:25:11 -07:00
Hamish Knight
95d0ebdb9b Adjust BriefCommentRequest to only query swiftdoc if we have it
If we have both loaded a swiftdoc, and the decl we
have should have had its doc comment serialized into
it, we can check it without needing to fall back
to the swiftsourceinfo.

This requires a couple of refactorings:

- Factoring out the `shouldIncludeDecl` logic
into `getDocCommentSerializationTargetFor` for
determining whether a doc comment should end up
in the swiftdoc or not.
- Factoring out `CommentProviderFinder` for searching
for the doc providing comment decl for brief
comments, in order to allow us to avoid querying
the raw comment when searching for it. This has the
added bonus of meaning we no longer need to fall
back to parsing the raw comment for the brief
comment if the comment is provided by another decl
in the swiftdoc.

This diff is best viewed without whitespace.
2023-04-26 12:38:38 +01:00
Ellie Shin
b081404daa Print package-name in .private.swiftinterface only for better abstraction
Resolves rdar://107638447
2023-04-20 17:45:22 -07:00
Artem Chikin
4e520e44a2 [Dependency Scanning] Pull required dependencies from the adjacent binary module for direct '@testable' interface dependencies
They may be a super-set of the ones that appear in the textual interface - e.g. 'internal' imports will be contained in the adjacent binary module, but not the textual interface
2023-04-17 16:49:34 -07:00
Artem Chikin
6fcd8be072 [Dependency Scanning] Pull optional dependencies from the adjacent binary module for direct interface dependencies
For a `@Testable` import in program source, if a Swift interface dependency is discovered, and has an adjacent binary `.swiftmodule`, open up the module, and pull in its optional dependencies. If an optional dependency cannot be resolved on the filesystem, fail silently without raising a diagnostic.
2023-04-17 14:47:46 -07:00
Artem Chikin
0067c415c4 Factor out reading in Binary module dependency imports from 'SerializedModuleLoaderBase::scanModuleFile'. 2023-04-17 13:34:06 -07:00
Doug Gregor
f7e479759d Merge pull request #64854 from DougGregor/top-level-macro-lookup 2023-04-03 06:50:39 -07:00
Doug Gregor
828de17b00 [Macros] Resolve macro names using unqualified lookup that ignores expansions
The macro name resolution in the source lookup cache was only looking at
macros in the current module, meaning that any names introduced by peer
or declaration macros declared in one module but used in another would
not be found by name lookup.

Switch the source lookup cache over to using the same
`forEachPotentialResolvedMacro` API that is used by lookup within
types, so we have consistent name-lookup-level macro resolution in both
places.

... except that would be horribly cyclic, of course, so introduce name
lookup flags to ignore top-level declarations introduced by macro
expansions. This is semantically correct because macro expansions are
not allowed to introduce new macros anyway, because that would have
been a terrible idea.

Fixes rdar://107321469. Peer and declaration macros at module scope
should work a whole lot better now.
2023-04-02 23:15:38 -07:00
Richard Wei
eb8e984b97 [Macros] Private discriminators for outermost-private MacroExpansionDecl (#64813)
Add a private discriminator to the mangling of an outermost-private `MacroExpansionDecl` so that declaration macros in different files won't have colliding macro expansion buffer names.

rdar://107462515
2023-03-31 20:36:29 -07:00
Alexis Laferrière
9e18563faf [Sema] Support -testable-import-module to load transitive non-public dependencies
When using the -testable-import-module argument to insert a testable
import, there's no ImportDecl on which to show the diagnostics when
loading transitive dependencies. Clean up the logic to still load
dependencies in such a case.
2023-03-29 13:59:29 -07:00
Alexis Laferrière
f7f69c6ae1 [Serialization] Load non-public transitive dependencies on @testable imports
A @testable import allows a client to call internal decls which may
refer to non-public dependencies. To support such a use case, load
non-public transitive dependencies of a module when it's imported
@testable from the main module.

This replaces the previous behavior where we loaded those dependencies
for any modules built for testing. This was risky as we would load more
module for any debug build, opening the door to a different behavior
between debug and release builds. In contrast, applying this logic to
@testable clients will only change the behavior of test targets.

rdar://107329303
2023-03-29 13:59:28 -07:00
Alexis Laferrière
87431a7a66 [Serialization|NFC] Split diagnoseSerializedASTLoadFailure in two
The new diagnoseSerializedASTLoadFailureTransitive diagnose problems for
transitive dependencies only: missing dependency, missing underlying
module, or circular dependency.
2023-03-29 13:59:28 -07:00
Ellie Shin
c2bb890f63 Merge pull request #64488 from apple/es-load
Do not load modules of the same package if built from interface
2023-03-22 23:26:12 -07:00
Ellie Shin
fc2b61da71 - Do not load modules of the same package if built from interface.
- Show diagnostics with an interface path

Resolves rdar://104617990
2023-03-22 17:30:27 -07:00
Alexis Laferrière
c2181b136d [Serialization] Use the new logic for transitive dependencies in the scanner 2023-03-20 14:03:45 -07:00
Alexis Laferrière
61c0827427 [Serialization] Refactor logic deciding transitive module loading logic
Refactor and centralize the logic about how implementation-only and
package-only dependencies should be loaded.
2023-03-20 13:53:10 -07:00
Alexis Laferrière
2a7aa37cd5 Merge pull request #64074 from xymus/report-mismatching-module-version-to-stderr
[Serialization] Remark only on stderr when loading a mismatching swiftmodule
2023-03-03 15:14:37 -08:00
Alexis Laferrière
5be7e2d1d5 [Serialization] Load indirect package dependencies from the current package
When loading a swiftmodule A, read its package information to tell if
the current client should load A's dependencies imports by a package
import. Only clients belonging to the same package as A should load
those dependencies, clients outside of the package likely don't have
access to those dependencies.

This is specific to swiftmodules as swiftinterfaces never display a
package-only import. Clients are unaware of package dependencies when
building against a swiftinterface.

rdar://106164813
2023-03-03 11:43:21 -08:00
Alexis Laferrière
f4bb6dc9ec [Serialization] Remark on stderr when loading a mismatching swiftmodule
Swiftmodules built by a mismatching compiler are loaded if the mismatch
is only on the last digit of the compiler version. In such a case, write
a remark directly to stderr to avoid showing this error in IDE but keep
it for debugging purposes.

rdar://105881894
2023-03-03 10:46:27 -08:00
Alexis Laferrière
9a1a32cd9b Merge pull request #63639 from xymus/serial-precise-tag
[Serialization] Don't fail the precise tag check if only the last digit doesn't match
2023-02-14 09:31:31 -08:00
Alexis Laferrière
a5ccbf3264 [Serialization] Only remark if the last digit mismatches in precise tag check
Weaken the precise tag check at loading swiftmodule to accept binary
modules build by a compiler with a tag where only the last digit is
different. We assume that the other digit in the version should ensure
compiler and stdlib compatibility. If the last digit doesn't match,
still raise a remark.

rdar://105158258
2023-02-13 14:28:10 -08:00
Ben Barham
6269643b4d [Index] Prevent re-indexing system modules repeatedly
If a module was first read using the adjacent swiftmodule and then
reloaded using the swiftinterface, we would do an up to date check on
the adjacent module but write out the unit using the swiftinterface.
This would cause the same modules to be indexed repeatedly for the first
invocation using a new SDK. On the next run we would instead raad the
swiftmodule from the cache and thus the out of date check would match
up.

The impact of this varies depending on the size of the module graph in
the initial compilation and the number of jobs started at the same time.
Each SDK dependency is re-indexed *and* reloaded, which is a drain on
both CPU and memory. Thus, if many jobs are initially started and
they're all going down this path, it can cause the system to run out of
memory very quickly.

Resolves rdar://103119964.
2023-02-09 11:49:13 -08:00
Artem Chikin
957f49add9 [Dependency Scanning] Do not process transitive '@_implementationOnly' dependencies of binary Swift modules
These modules are not guaranteed to be found, which is okay, as compilation is meant to be possible in their absense since their contents are not used in the public API of the module which imports them as implementation-only.

Resolves rdar://103031296
2023-01-30 14:25:23 -08:00
Artem Chikin
12477b7b79 [Dependency Scanning] Refactor the scanner to resolve unqualified module imports
This changes the scanner's behavior to "resolve" a discovered module's dependencies to a set of Module IDs: module name + module kind (swift textual, swift binary, clang, etc.).

The 'ModuleDependencyInfo' objects that are stored in the dependency scanner's cache now carry a set of kind-qualified ModuleIDs for their dependencies, in addition to unqualified imported module names of their dependencies.

Previously, the scanner's internal state would cache a module dependnecy as having its own set of dependencies which were stored as names of imported modules. This led to a design where any time we needed to process the dependency downstream from its discovery (e.g. cycle detection, graph construction), we had to query the ASTContext to resolve this dependency's imports, which shouldn't be necessary. Now, upon discovery, we "resolve" a discovered dependency by executing a lookup for each of its imported module names (this operation happens regardless of this patch) and store a fully-resolved set of dependencies in the dependency module info.

Moreover, looking up a given module dependency by name (via `ASTContext`'s `getModuleDependencies`) would result in iterating over the scanner's module "loaders" and querying each for the module name. The corresponding modules would then check the scanner's cache for a respective discovered module, and if no such module is found the "loader" would search the filesystem.

This meant that in practice, we searched the filesystem on many occasions where we actually had cached the required dependency, as follows:
Suppose we had previously discovered a Clang module "foo" and cached its dependency info.
-> ASTContext.getModuleDependencies("foo")
--> (1) Swift Module "Loader" checks caches for a Swift module "foo" and doesn't find one, so it searches the filesystem for "foo" and fails to find one.
--> (2) Clang Module "Loader" checks caches for a Clang module "foo", finds one and returns it to the client.

This means that we were always searching the filesystem in (1) even if we knew that to be futile.
With this change, queries to `ASTContext`'s `getModuleDependencies` will always check all the caches first, and only delegate to the scanner "loaders" if no cached dependency is found. The loaders are then no longer in the business of checking the cached contents.

To handle cases in the scanner where we must only lookup either a Swift-only module or a Clang-only module, this patch splits 'getModuleDependencies' into an alrady-existing 'getSwiftModuleDependencies' and a newly-added 'getClangModuleDependencies'.
2023-01-05 11:44:06 -08:00
Ellie Shin
7323d32ea4 Merge pull request #62700 from apple/es-pkg1
Add -package-name flag and de/serialize package name in module binary
Resoles rdar://103531218, rdar://103531208
2022-12-19 23:43:37 -08:00
Ellie Shin
72ee150982 Add -package-name flag
De/serialize package name in module binary
Resoles rdar://103531218, rdar://103531208
2022-12-19 14:33:44 -08:00
Artem Chikin
1230966e80 [Dependency Scanner] Rename 'ModuleDependenceis' -> 'ModuleDependencyInfo' 2022-12-15 14:18:29 -08:00
Artem Chikin
3db767843e [Dependency Scanning] Record whether discovered binary Swift modules are frameworks
Part of rdar://102824777
2022-12-13 10:44:37 -08:00
Xi Ge
afbc4a5ffd Merge pull request #62251 from nkcsgexi/allowable-serialization
serialization: encode allowable client names in binary module format
2022-11-28 18:12:43 -08:00
Alexis Laferrière
c266e9dce5 Merge pull request #62185 from xymus/improve-rmodule-loading
Improve `-Rmodule-loading` to show both the path to the source and to the cached file actually loaded
2022-11-28 14:25:15 -08:00
Xi Ge
5987654b3a Merge branch 'main' into allowable-serialization 2022-11-28 09:36:04 -08:00
Xi Ge
67bbab7e02 serialization: encode allowable client names in binary module format 2022-11-25 18:43:40 -08:00
Erik Eckstein
ab1b343dad use new llvm::Optional API
`getValue` -> `value`
`getValueOr` -> `value_or`
`hasValue` -> `has_value`
`map` -> `transform`

The old API will be deprecated in the rebranch.
To avoid merge conflicts, use the new API already in the main branch.

rdar://102362022
2022-11-21 19:44:24 +01:00
Alexis Laferrière
319d49816d [Frontend] -Rmodule-loading shows both source path and cached path 2022-11-18 15:28:16 -08:00
Alexis Laferrière
552d3a4984 [Sema] Restrict reexported SPIs to modules with an export_as relationship
@_exported exports SPIs only when the exported module defines export_as
pointing to the exporter module. Other reexports do not reexport SPIs.
This is to prevent SPI reexporting to get out of hands with the wide
reexports of the Objective-C world.

rdar://102335473
2022-11-14 13:17:55 -08:00
Alexis Laferrière
c0abde01a2 [Sema] @_exported imports export @_spi decls too
Enable transitive imports of all SPI groups through @_exported imports.
This brings to SPI the same behavior that we have for API.

```
// Module A
@_spi(S) public func foo() {}

// Module B
@_exported import A

// Module C
@_spi(S) import B

foo() // SPI imported through the reexport of A from B
```

rdar://101566534
2022-11-10 16:46:14 -08:00
Alexis Laferrière
3ca1de0a0f [Sema] Clean up lookupImportedSPIGroups 2022-11-08 16:35:43 -08:00
Alexis Laferrière
47b29b68db Merge pull request #61649 from xymus/index-swiftinterfaces
[Index] Force indexing of system modules to read only from swiftinterfaces
2022-10-31 14:18:45 -07:00
Richard Wei
4ce1ebb120 [Macros] Support user-defined macros as compiler plugins (#61734)
Allow user-defined macros to be loaded from dynamic libraries and evaluated.

- Introduce a _CompilerPluginSupport module installed into the toolchain. Its `_CompilerPlugin` protocol acts as a stable interface between the compiler and user-defined macros.
- Introduce a `-load-plugin-library <path>` attribute which allows users to specify dynamic libraries to be loaded into the compiler.

A macro library must declare a public top-level computed property `public var allMacros: [Any.Type]` and be compiled to a dynamic library. The compiler will call the getter of this property to obtain and register all macros.

Known issues:
- We current do not have a way to strip out unnecessary symbols from the plugin dylib, i.e. produce a plugin library that does not contain SwiftSyntax symbols that will collide with the compiler itself.
- `MacroExpansionExpr`'s type is hard-coded as `(Int, String)`. It should instead be specified by the macro via protocol requirements such as `signature` and `genericSignature`. We need more protocol requirements in `_CompilerPlugin` to handle this.
- `dlopen` is not secure and is only for prototyping use here.

Friend PR: apple/swift-syntax#1022
2022-10-31 14:03:25 -07:00
Alexis Laferrière
730497e9a3 [Serialization] Add control over adding a loaded module to the in-memory cache 2022-10-31 10:58:57 -07:00
Alexis Laferrière
83cd432785 [Frontend] Intro global control to force loading from swiftinterface
Intro ASTContext::setIgnoreAdjacentModules to change module loading to
accept load only resilient modules from their swiftinterfaces, ignoring
the adjacent module and any silencing swiftinterfaces errors.
2022-10-31 10:58:54 -07:00
Alexis Laferrière
2854c1b3cb [Serialization] Write in the swiftmodule if it's built from a swiftinterface
This information will allow us to distinguish swiftmodule built from
source vs swiftinterface.
2022-10-27 18:51:28 -07:00
Adrian Prantl
3cc2831608 Don't require a strict revision match in LLDB.
For release-management purposes during development, LLDB's embedded Swift
compiler's version number can sometimes be off-by-one in the last digit
compared to the Swift compiler.

This patch restores the old behavior from before 17183629e4.

rdar://101299168
2022-10-19 09:03:13 -07:00
Allan Shortlidge
bbf189c8ab AST: Make the versioned variants of #if canImport() more reliable and consistent.
Previously, when evaluating a `#if canImport(Module, _version: 42)` directive the compiler could diagnose and ignore the directive under the following conditions:

- The associated binary module is corrupt/bogus.
- The .tbd for an underlying Clang module is missing a current-version field.

This behavior is surprising when there is a valid `.swiftinterface` available and it only becomes apparent when building against an SDK with an old enough version of the module that the version in the `.swiftinterface` is too low, making this failure easy to miss. Some modules have different versioning systems for their Swift and Clang modules and it can also be intentional for a distributed binary `.swiftmodule` to contain bogus data (to force the compiler to recompile the `.swiftinterface`) so we need to handle both of these cases gracefully and predictably.

Now the compiler will enumerate all module loaders, ask each of them to attempt to parse the module version and then consistently use the parsed version from a single source. The `.swiftinterface` is preferred if present, then the binary module if present, and then finally the `.tbd`. The `.tbd` is still always used exclusively for the `_underlyingVersion` variant of `canImport()`.

Resolves rdar://88723492
2022-09-07 14:18:05 -07:00
swift-ci
5c8f1fcb12 Merge remote-tracking branch 'origin/main' into rebranch 2022-07-02 17:03:37 -07:00
swift-ci
8364d5b3d7 Merge pull request #40777 from ApolloZhu/fix-canImport-submodule-checking
Fix canImport submodule checking in loaders not supporting submodules
2022-07-01 15:10:13 -07:00
swift-ci
55000f53be Merge remote-tracking branch 'origin/main' into rebranch 2022-06-17 10:15:14 -07:00