Commit Graph

134 Commits

Author SHA1 Message Date
Artem Chikin
50c0dd844f [Dependency Scanning] Refactor 'createScanQueryContext' to directly return an error 2025-09-12 15:50:40 -07:00
Artem Chikin
c82048559a [Dependency Scanning] Configure a thread-safe serialized diagnostics consumer for in-memory scans
This change introduces a thread-safe version of the 'SerializedDiagnosticConsumer' and refactors scanning compilation instance creation code to ensure this consumer gets added when the scanner query configuration command-line includes '-serialized-diagnostics-path' option.
2025-09-11 09:50:24 -07:00
Artem Chikin
1cd1193e6c [Dependency Scanning] Give each scanner worker a unique Diagnostic Engine
Otherwise, when multiple workers encounter a diagnostic simultaneously we can encounter races which lead to corrupted diagnostic data or crashes

Resolves rdar://159598539
2025-09-03 13:52:44 -07:00
Artem Chikin
89b43dccf3 Merge pull request #83600 from artemcm/NoRedundantClangDepBridging
[Dependency Scanning] Bridge Clang dependency scanner results on-demand
2025-08-18 09:36:27 -07:00
Artem Chikin
b14cbbb039 [Dependency Scanning] Add serialization of optional imports to the JSON output
And to the corresponding graph data structure the output gets generated from
2025-08-15 16:11:13 -07:00
Artem Chikin
9f0083c7c0 [Dependency Scanning] Refactor Clang dependency bridging into a 'ModuleDependencyScanner' utility
This moves the functionality of 'bridgeClangModuleDependency' into a utility in the main scanner class because it relies on various objects whose lifetime is already tied to the scanner itself.
2025-08-15 15:40:41 -07:00
Artem Chikin
5015ba683a [Dependency Scanning] Bridge Clang dependency scanner results on-demand
Instead of always bridging all of the discovered modules of all of the queries, only do so for modules which are not already cached
2025-08-15 14:55:42 -07:00
Artem Chikin
f7bc37410e Merge pull request #83532 from artemcm/AdjustDarwinCxxInteropCycleHack
[Dependency Scanning][C++ Interop] Avoid `CxxStdlib` overlay lookup for binary Swift dependencies which were not built with C++ interop
2025-08-13 15:29:14 -07:00
Artem Chikin
56a6c14ba0 [Dependency Scanning] Reduce the amount of copying of collections of module IDs
Previously, frequently-used methods like 'getAllDependencies' and 'getAllClangDependencies' had to aggregate (copy) multiple collections stored in a 'ModuleDependencyInfo' into a new result array to present to the client. These methods have been refactored to instead return an iterable joined view of the constituent collections.
2025-08-11 12:18:56 -07:00
Artem Chikin
77a61a242f [Dependency Scanning][C++ Interop] Avoid 'CxxStdlib' overlay lookup for binary Swift dependencies which were not built with C++ interop
In addition to skipping it on textual Swift module dependencies which were built without C++ interop enabled, also skip it over similarly on binary Swift dependencies
2025-08-07 10:41:00 -07:00
Artem Chikin
242585dcba [Dependency Scanning] Restrict Swift overlay lookup to "visible" Clang modules only
Previously Swift overlay lookup was performed for every directly and transitively-imported Clang module.

https://github.com/llvm/llvm-project/pull/147969 introduced the concept of "visible" Clang modules from a given named Clang dependency scanner query which closely maps to the set of modules for which Swift will attempt to load a Swift overlay. This change switches overlay querying to apply only to the set of such visible modules.

Resolves rdar://144797648
2025-07-23 09:25:26 -07:00
Artem Chikin
8961d8da9a [Dependency Scanning] Diagnose an error when only finding incompatible Swift binary modules
When querying a Swift module, the scanner now also keeps track of all discovered candidate binary modules which are not compatible with current compilation.

- If a Swift dependency is successfully resolved to a compatible binary module or a textual interface, a warning is emitted for every incompatible binary Swift module discovered along the way.
- If a Swift dependency is not resolved, but incompatible module candidates were found, an error is emitted - while it is likely that the scan would fail downstream, it is also possible that an underlying Clang module dependency (with the same name) is successfuly resolved and the Swift lookup failure is ignored, which is still going to lead to failures most of the time if the client code assumes the presence of the Swift overlay module in this scenario.

This change refactors common error reporting by the scanner into a 'ModuleDependencyIssueReporter' class, which also keeps track of all diagnosed failed lookups to avoid repeating diagnostics.
2025-07-07 11:11:34 -07:00
Steven Wu
2a18922c4b [Caching] Move per-query CAS state out of the SwiftDependencyScanningService
Move per-query state out of ScanningService. There is still a check to
make sure the CASOptions are matching between queries because of the
requirement on clang scanner. Otherwise, the scanning service should
contain no per-query information anymore.

Resolves: https://github.com/swiftlang/swift/issues/82490
2025-06-26 17:03:27 -07:00
Artem Chikin
39c096c388 [Dependency Scanning] Refactor 'ModuleDependenciesCache' to not hold a reference to the global 'SwiftDependencyScanningService'
While this made sense in the distant past where the scanning service provided backing storage for the dependency cache, it no longer does so and now makes for awkard layering where clients get at the service via the cache. Now the cache is a simple data structure while all the clients that need access to the scanning service will get it explicitly.
2025-06-23 13:39:43 -07:00
Artem Chikin
68883a1014 [Dependency Scanning] Refactor Swift Scanner loader to be standalone
- 'SwiftModuleScanner' will now be owned directly by the 'ModuleDependencyScanningWorker' and will contain all the necessary custom logic, instead of being instantiated by the module interface loader for each query
- Moves ownership over module output path and sdk module output path directly into the scanning worker, instead of the cache
2025-06-23 13:39:36 -07:00
Artem Chikin
5eb85acad5 Merge pull request #82031 from artemcm/RemovePlaceholdersInDepScanner
[Dependency Scanning] Remove obsolete placeholder module concept
2025-06-18 12:40:30 -07:00
Artem Chikin
a78ee29692 [Dependency Scanning] Remove obsolete placeholder module concept
This was used a long time ago for a design of a scanner which could rely on the client to specify that some modules *will be* present at a given location but are not yet during the scan. We have long ago determined that the scanner must have all modules available to it at the time of scan for soundness. This code has been stale for a couple of years and it is time to simplify things a bit by deleting it.
2025-06-12 08:32:25 -07:00
Artem Chikin
c3ce91e071 [Dependency Scanning] Add libSwiftScan API and JSON output for source import information 2025-06-12 06:56:33 -07:00
Artem Chikin
6816922dd4 [Dependency Scanning] Keep track of each imported module's access control
Adds an access control field for each imported module identified. When multiple imports of the same module are found, this keeps track of the most "open" access specifier.
2025-06-12 06:56:30 -07:00
Artem Chikin
d4abba10a5 Add a new diagnostic group and documentation for the module-not-found failure which specifies that a missing module dependency can be found on a search path serialized in another Swift binary module dependency. 2025-06-04 16:57:01 -07:00
Artem Chikin
aedc2fadb3 [Dependency Scanning] Serialized Swift binary module serialized search paths 2025-06-04 16:55:45 -07:00
Artem Chikin
90f2fba2ae [Dependency Scanning] On failure to locate a module, attempt to diagnose if binary dependencies contain search paths with this module.
Unlike with implicitly-built modules (prior to Swift 6 mode), explicitly-built modules require that all search paths be specified explicitly and no longer inherit search paths serialized into discovered Swift binary modules. This behavior was never intentional and is considered a bug. This change adds a diagnostic note to a scan failure: for each binary Swift module dependency, the scanner will attempt to execute a dependency scanning query for each serialized search path inside that module. If such diagnostic query returns a result, a diagnostic will be emitted to inform the user that the dependency may be found in the search path configuration of another Swift binary module dependency, specifying which search path contains the "missing" module, and stating that such search paths are not automatically inherited by the current compilation.
2025-06-04 16:55:37 -07:00
Artem Chikin
c4fcee0875 [Dependency Scanning][C++ Interop] Remap lookup of Clang module 'CxxStdlib' to 'std'
Otherwise querying this clang module, e.g. from the corresponding Swift overlay's underlying module import, will fail, since no such module exists.

Resolves rdar://151718115
2025-05-21 09:54:28 -07:00
Artem Chikin
8cd193fc08 [Dependency Scanning] Remove 'ClangImporter' instance from dependency scanning worker
Move relevant logic directly into the worker
2025-05-07 16:43:45 -07:00
Artem Chikin
c1991d7e7e [Dependency Scanning][libSwiftScan] Deprecate scanner-global diagnostic collection
All clients are expected to have switched to the per-scan-query diagnostics using 'swiftscan_dependency_graph_get_diagnostics'
2025-05-05 10:33:15 -07:00
Artem Chikin
fd0e55143f [Dependency Scanning] Always use a locking diagnostic consumer
Since we enabled parallel dependency scanning by-default, each individual scan needs a diagnostic consumer that is safe to use across many threads. Deprecate the 'Locking' sub-class, making its behavior the default in the base class.
2025-05-05 10:25:49 -07:00
Artem Chikin
a448cef35f Include system-ness of framework and import search paths in the PCH hash
This hash is also used for the dependency scanning hash. In both cases, PCH contents may differ based on whether a certain module they depend on is found in a system or non-system search path. In dependency scanning, systemness should cause a full change of scanning context requiring a from-scratch scan.

Resolves rdar://150334077
2025-05-01 16:39:12 -07:00
Artem Chikin
7037893eb3 [Dependency Scanning][Serialization] Do not serialize auxiliary files
The field is only used to store information to be used in finalize stage, in caching builds. When loading scan results from the cache, the entries are finalized already and have the file info encoded in CASIDs already.

Resolves rdar://150307865
2025-05-01 12:49:16 -07:00
Artem Chikin
7c5d8b24d3 [Dependency Scanning] Add a field of source-imported dependencies
For the main source module, provide info on which dependencies are directly imported into the user program, explicitly ('import' statement) or implicitly (e.g. stdlib). Thist list does not include Swift overlay dependencies, cross-import dependencies, bridging header dependencies.
2025-04-30 10:15:20 -07:00
Artem Chikin
88dec5199e [Dependency Scanning] Add support for placing explicitly-built SDK modules into a separate module cache
With '-sdk-module-cache-path', Swift textual interfaces found in the SDK will be built into a separate SDK-specific module cache.
Clang modules are not yet affected by this change, pending addition of the required API.
2025-03-19 09:17:04 -06:00
Artem Chikin
0555764bb4 [Dependency Scanning] Refine cross-import overlay detection algorithm
The algorithm already performs pairwise checks on module dependencies brought into compilation per-source-file. Previously, the algorithm considered the entire sub-graph of a given source file. Actual source compiles do not consider the full transitive module dependency set for cross-import-overlay lookup, but rather only directly-imported modules in a given source file, and '@_exported import' Swift transitive dependencies.

This change adds tracking of whether a given import statement is 'exported' to the dependency scanner and then refines the cross-import overlay lookup logic to only consider transitive modules that are exported by directly-imported dependencies.
2025-02-27 15:48:11 -08:00
Artem Chikin
809dbf0994 [Dependency Scanning] Keep track of whether a given Swift 'import' statement is '@_exported' 2025-02-26 15:52:46 -08:00
Artem Chikin
14dd14d1a4 Merge pull request #79550 from artemcm/EBM_CrossImportsPerSourceFile
[Dependency Scanning] Perform cross-import overlay resolution per source-file
2025-02-25 20:36:33 -08:00
Artem Chikin
214fe59139 [Dependency Scanning] Perform cross-import overlay resolution per source-file
Previous implementation took the entire transitive dependency set and cross-referenced all of its members to determine which ones introduce requried cross-import overlays. That implementation differed from the cross-import overlay loading logic during source compilation, where a corrsponding cross-import overlay module is only requested if the two constituent modules are reachable via direct 'import's from *the same source file*. Meaning the dependency scanner before this change would report cross-import overlay dependencies which never got loaded by the corresponding client source compile.

This change implements a new implementation of cross-import overlay discovery which first computes sub-graphs of module dependencies directly reachable by 'import's for each source file of the module under scan and then performs pairwise cross-import overlay query per each such sub-graph.

Resolves rdar://145157171
2025-02-25 13:40:23 -08:00
Yuta Saito
d6fef4220d [DependencyScan] Use llvm::DefaultThreadPool instead of llvm::StdThreadPool
`llvm::StdThreadPool` is only available when LLVM_ENABLE_THREADS is enabled.
LLVM defines `DefaultThreadPool` type alias, which is always available
regardless of the threads enabled. This change allows building the library
without threads enabled, especially for Emscripten toolchain.

  ```
  #if LLVM_ENABLE_THREADS
  using DefaultThreadPool = StdThreadPool;
  #else
  using DefaultThreadPool = SingleThreadExecutor;
  #endif
  ```
2025-02-13 00:25:54 +00:00
Steven Wu
0f01cffbd6 Merge pull request #79172 from cachemeifyoucan/eng/caching-scanning-result-cas
[Dependency Scanning] Support loading scanner cache state for caching
2025-02-07 10:26:00 -08:00
Saleem Abdulrasool
9c85fbc8da AST,DependencyScan,IRGen,Serialization,Tooling: track library style (#78777)
Track if the dependency is static or dynamic. This is in preparation for
helping rename the static library to differentiate it from import
libraries.
2025-02-06 13:22:56 -08:00
Steven Wu
ca749de113 [Dependency Scanning] Support loading scanner cache state for caching
Teach scanner cache loader to validate the CAS contents when validating
dependency graph loaded.
2025-02-05 14:24:35 -08:00
Steven Wu
9d59044bb1 [BrdigingHeader] Auto bridging header chaining
Add ability to automatically chaining the bridging headers discovered from all
dependencies module when doing swift caching build. This will eliminate all
implicit bridging header imports from the build and make the bridging header
importing behavior much more reliable, while keep the compatibility at maximum.

For example, if the current module A depends on module B and C, and both B and
C are binary modules that uses bridging header, when building module A,
dependency scanner will construct a new header that chains three bridging
headers together with the option to build a PCH from it. This will make all
importing errors more obvious while improving the performance.
2025-02-05 09:41:04 -08:00
Artem Chikin
acb4e847f5 [Dependency Scanning] Add functionality to validate contents of a loaded scanner cache state
Checking each module dependency info if it is up-to-date with respect to when the cache contents were serialized in a prior scan.

- Add a timestamp field to the serialization format for the dependency scanner cache
- Add a flag "-validate-prior-dependency-scan-cache" which, when combined with "-load-dependency-scan-cache" will have the scanner prune dependencies from the deserialized cache which have inputs that are newer than the prior scan itself

With the above in-place, the scan otherwise proceeds as-is, getting cache hits for entries still valid since the prior scan.
2025-02-03 10:33:43 -08:00
Artem Chikin
477ba0dd97 [Dependency Scanning] Remove references to per-triple PCM variant compilation 2025-01-29 11:32:07 -08:00
Artem Chikin
41e471288a [Dependency Scanning] Deprecate/Remove batch scanning capability
Batch dependency scanning was added as a mechanism to support multiple compilation contexts within a single module dependency graph.
The Swift compiler and the Explicitly-built modules model has long since abandoned this approach and this code has long been stale. It is time to remove it and its associated C API.
2025-01-28 15:30:39 -08:00
Artem Chikin
5961b9a00b [Dependency Scanning] Only reuse serialized scanner caches with matching scanning context hash 2025-01-06 09:09:32 -08:00
Artem Chikin
48387eed55 [Dependency Scanning] Keep track of how many filesystem module lookups the dependency scanner performs on a given scan 2025-01-06 09:09:32 -08:00
Artem Chikin
25d32fc7a3 [Dependency Scanning] Add import statement source locations to the dependency scanner cache serialization format 2025-01-06 09:09:32 -08:00
Artem Chikin
b8d1960148 [Dependency Scanning] Add Macro Dependencies to the dependency scanner cache serialization format 2025-01-06 09:09:31 -08:00
Artem Chikin
6fdb788b7e [Dependency Scanning] Add Link Libraries to the dependency scanner cache serialization format 2025-01-06 09:09:31 -08:00
Artem Chikin
a46e33143a [Dependency Scanning] Modernize and revive the module dependencies cache serialization format
This format has gotten stale and been not in use for many months. This commit restores primary functionality of the format.
2025-01-06 09:09:27 -08:00
Artem Chikin
9055a401a3 [Dependency Scanner] Refactor the global scanning service to no longer maintain scanner cache state
Instead, each scan's 'ModuleDependenciesCache' will hold all of the data corresponding to discovered module dependencies.

The initial design presumed the possibility of sharing a global scanning cache amongs different scanner invocations, possibly even different concurrent scanner invocations.

This change also deprecates two libSwiftScan entry-points: 'swiftscan_scanner_cache_load' and 'swiftscan_scanner_cache_serialize'. They never ended up getting used, and since this code has been largely stale, we are confident they have not otherwise had users, and they do not fit with this design.

A follow-up change will re-introduce moduele dependency cache serialization on a per-query basis and bring the binary format up-to-date.
2024-12-04 11:13:05 -08:00
Artem Chikin
717002d405 [Dependency Scanning] Copy the set of already-seen clang modules before parallel Clang identifier query
This set, belonging to 'ModuleDependenciesCache', is only updated in a critical section behind a lock in the scanner. However, it is queried unsynchronized inside the Clang scanner itself. If an update causes a re-hash to happen, chaose can ensue with concurrent lookups.

Since this set only affects the produced set of results from teh Clang scanning query, we should simply pass in an immutable copy to scanning queries and rely on downstream de-duplication of scanning results.

With this, we can avoid passing in the reference to `ModuleDependenciesCache` to the 'scanFilesystemFor*ModuleDependency' altogether.

Resolves rdar://139414443
2024-11-07 14:08:58 -08:00