Commit Graph

156 Commits

Author SHA1 Message Date
Steven Wu 38cf5f87f4 [DependencyScan][Caching] Do not mix CAS instance
Make sure the CAS instances are not mixed during dependency scanning,
especially when used from libSwiftScan C APIs.

For clang scanning service and file system, it should always be created
from the global CAS instance.

For CAS instance inside the swift instance when performing dependency
scanning, it reuse the CAS instance from global as well if that is
already initialized.

rdar://173703843
2026-04-01 11:46:17 -07:00
Ben Langmuir 768fb73f8b Merge pull request #87862 from benlangmuir/casoptions-adaptation
[cas] Adapt to clang::CASOptions change to remove internal cache of instances
2026-03-19 09:42:20 -07:00
Steven Wu 3ba1ba45d4 Merge pull request #87892 from cachemeifyoucan/eng/PR-172693314
[DependencyScan] Propagate module library level through dependency scanner for CAS builds
2026-03-18 09:08:27 -07:00
Steven Wu 34d52cfe1a [DependencyScan] Propagate module library level through dependency scanner for CAS builds
Compute and propagate the library level (api/spi/ipi) of each module
dependency through the dependency scanner so that the compiler can
correctly enforce private module import diagnostics in CAS mode, where
path-based SPI detection fails because CAS abstracts file paths to
content IDs.

Swift modules:
- Detect library level from the module interface path using
  libraryLevelFromPath() during scanning, for both textual (.swiftinterface)
  and binary (.swiftmodule) Swift modules.

Clang modules:
- Expose ModuleMapIsPrivate from clang::Module in ModuleDeps via the
  dependency scanning infrastructure.
- Set library level for clang modules in bridgeClangModuleDependency()
  using ModuleMapIsPrivate (catches module.private.modulemap in any
  SDK location) and libraryLevelFromPath() on the module map file
  (catches modules under PrivateFrameworks directories).

The library level is:
- Stored in ModuleDependencyInfo and serialized in the module dependency
  cache (format version bumped to v8).
- Exposed through the swiftscan C API via a new
  swiftscan_module_info_get_library_level() function (API minor version
  bumped to 3).
- Emitted in the dependency scanner JSON output as "libraryLevel" for
  all module kinds (Swift textual, Swift binary, Clang, and main module).
- Parsed from the explicit module map JSON by ExplicitModuleMapParser
  for both Swift (ExplicitSwiftModuleInputInfo) and Clang
  (ExplicitClangModuleInputInfo) modules.
- Looked up in ModuleLibraryLevelRequest via
  ASTContext::getExplicitModuleLibraryLevel(name, isClang), which
  consults the appropriate map (Swift or Clang) based on module kind.

rdar://172693314

Assisted-By: Claude
2026-03-17 11:04:18 -07:00
Artem Chikin a21b400fca [NFC][Dependency Scanning] Small linter fixes
- Remove unused headers
- Sort headers
- Extend anonymous namespace in DependencyScanJSON.cpp
2026-03-16 12:07:14 +00:00
Steven Wu f620d37dda Reapply: [Caching][NFC] Using llvm::cas::CASConfiguration
This no longer causes a regression in number of CAS instances.

Prefer llvm::cas::CASConfiguration where it used to clang::CASOption.

(cherry picked from commit 4f059033bb)
2026-03-13 15:41:36 -07:00
Steven Wu 7fdf642819 [ExplicitModule] Teach scanner emit loaded module trace
During explicit module build, teach dependency scanner to emit the
module trace file instead of each following compile job command. This
reduces the duplicated info, and allows supporting fully cached build
that only loads module from CAS thus cannot produce the path to the
original module file on disk.

rdar://170007480
2026-02-18 09:10:08 -08:00
Hiroshi Yamauchi 36be4d294e Remove Clang CASFS (#86973) 2026-02-05 19:32:08 -08:00
Artem Chikin ad3d2d8aa5 Add caching of unsuccessful Swift dependency lookups
Use it to avoid unnecessary re-queries of Swift dependencies during a given scanning action.

Refactor 'hasSwiftDependency' API into 'hasQueriedSwiftDependency' to instead report whether or not the cache has recorded a prior lookup of a given Swift dependency.
2026-01-22 12:19:27 +00:00
Artem Chikin 9c97a6fc3a Merge pull request #86101 from artemcm/RemoveDuplicateClangLookups
[Dependency Scanning] Re-use cached queried Clang dependency info in subsequent scanning stages
2026-01-09 20:15:07 -08:00
Steven Wu a9aa57ee0b Reapply "[DependencyScan] Correct setup clang VFS for dependency scanning"
This reverts commit e60ae24052 and fix
non-deterministic failures introduced by the commit.

Fix two issues when attempting to testing parallel scanning using
`swift-scan-test` tools:
* Make sure the BumpPtrAllocator in ScanningService is thread-safe so
  there are no race condition when a new slab is allocated.
* Make sure the output of `swift-scan-test` only written from one
  thread. This prevents some race conditions when writing to the same
  raw_fd_ostream.

rdar://167760262
2026-01-08 14:14:22 -08:00
Steven Wu e60ae24052 Revert "[DependencyScan] Correct setup clang VFS for dependency scanning"
This reverts commit e0e69f7ac0. This
causes flaky tests ScanDependencies/scanner_api_working_dir.swift.

rdar://167742034
2026-01-08 08:14:23 -08:00
Steven Wu e0e69f7ac0 [DependencyScan] Correct setup clang VFS for dependency scanning
Currently, dependency scanner is not reporting the redirecting files
that are baked inside swift-frontend for platform support. This causes
dependency scanner returns virtual path for those files, and
swift-driver/build-system will not be able to correct validate the files
on incremental build, causing incremental build to be almost clean
builds.

This behavior issue is caused by the dependency scanning file system
layer inside clang dependency scanner that caches stats. If the
redirecting files are created underneath the layer, the real path is
lost. This fixes the issue by moving the redirecting files above the
caching layer using `-ivfsoverlay` option.

In addition to that, this commit also unifies how clang importer and
clang dependency scanner initiate the VFS, making the logic much
simpler.
2026-01-07 10:00:25 -08:00
Artem Chikin 195bc1e6d6 [Dependency Scanning] Re-use cached queried Clang dependency info in subsequent scanning stages
Dependency Scanning is recursive over discovered Swift module overlays and cross-import overlays. In the main 'resolveImportedModuleDependencies' routine, after all Swift and Clang dependencies of the main module are discovered, the scanner looks up Swift overlays for discovered Clang modules. For each such Swift overlay, the scanner will then proceed to call 'resolveImportedModuleDependencies' on the overlay module.

On these subsequent recursive calls to 'resolveImportedModuleDependencies', Clang dependency resolution will re-query all imports of the overlay module which do not resolve to Swift modules, even if they had been queried previously in a parent invocation. This change adds the ability to re-use previously-queried-and-cached Clang module dependency information by having the dependency cache also store the set of visible modules which resulted from each by-name lookup.
2026-01-05 11:42:51 -08:00
Artem Chikin 7017034d20 [Dependency Scanning] Add tracking of the number of dependency queries and emit them as remarks
This change adds collection of three metrics to the scanner:
- number of Swift module lookups
- number of named Clang module lookups
- recorded number of Clang modules which were imported into a Swift module by name

It introduces '-Rdependency-scan', which acts as a super-set flag to the existing '-Rdependency-scan-cache' and adds emission of the above metrics as remarks when this flag is enabled. Followup changes will add further remarks about dependency scanner progress.
2025-12-17 12:50:33 -08:00
Steven Wu 8e68fab034 Revert "[Caching][NFC] Using llvm::cas::CASConfiguration"
This reverts commit 4f059033bb. The change
is actually not NFC since previously, there is a cache in the
CompilerInvocation that prevents the same CAS from the same CASOptions
from being initialized multiple times, which was relied upon when
running inside sub invocation. When switching to a non-caching simple
CASOption types, it causes every single sub instance will create its own
CAS, and it can consume too many file descriptors and causing errors
during dependency scanning.

rdar://164903080
2025-11-17 12:21:53 -08:00
Artem Chikin 8335a038bf [Dependency Scanning] Refactor batch clang dependency query to preserve only partial results
Previously, with the change to bridge Clang dependency scanning results on-demand, the scanner would execute Clang dependency scanning queries for each unresolved import, in parallel, and aggregate all of the results to post-process (including on-demand bridging) later. As a consequence of that change, all of the Clang scanner queries' results ('TranslationUnitDeps') got aggregated during a scan and had their lifetimes extended until a later point when they got processed and added to the scanner's cache.

This change refactors the Clang dependency scanner invocation to, upon query completion, accumulate only the 'ModuleDeps' nodes which have not been registered by a prior scan, discarding the rest of the 'TranslationUnitDeps' graph. The arrgegated 'ModuleDeps' objects are still bridged on-demand downstream.

This change further splits up the 'resolveAllClangModuleDependencies' method's functionality to improve readability and maintainability, into:
- 'gatherUnresolvedImports' method which collects all of collected Swift dependents' imports which did not get resolved to Swift dependencies
- 'performParallelClangModuleLookup' which actually executes the parallel queries and includes the new logic described above
- 'cacheComputedClangModuleLookupResults' method which takes the result of the parallel Clang scanner query and records in in the Swift scanner cache
- 'reQueryMissedModulesFromCache' method which covers the scenario where Clang scanner query returned no result because either the dependency can only be found transitively, or the query is for a dependency previously-queried.
2025-10-20 13:33:51 -07:00
Steven Wu 4f059033bb [Caching][NFC] Using llvm::cas::CASConfiguration
Prefer llvm::cas::CASConfiguration where it used to clang::CASOption.
2025-10-17 16:42:35 -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 27305d6ccc [Dependency Scanning] Ensure all direct Clang module imports from Swift modules are always queried by-name to the Clang dependency scanner
This is required in order to always have computed the set of visible Clang modules for each Swift module in the graph. Otherwise when some Clang module gets cached as a transitive dependency from a query and is later looked up as a direct dependency, there will not be any computed visible modules set.
2025-07-23 10:02:52 -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
Artem Chikin 0d3def55df [Dependency Scanning] Emit a note if a dependency cycle is between the source target and another Swift module with the same name
The note will point the user to where the "other" module with the same name is located and mention whether it is an SDK module. This is nice to have in various circumstances where developers attempt to define a module with the same name as a Swift module that already exists on their search paths, for example in the SDK.
2025-07-01 13:38:45 -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 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 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 a9e0a58b46 [Dependency Scanning] Add ClangImporter's mandatory path remaps to dependency scanning query filesystem
On creation, 'ClangImporter' adds overlay modulemap files for non-modular platform libraries (e.g. glibc, libstdc++), which allows Swift code to import and use those libraries.

This change adds the same filesystem overlay to dependency scanning queries by applying them to the filesystem instantiated for each depndency scanning worker. Without these overlays EBM builds cannot discover and use non-modular system libraries on non-Darwin platforms.

Resolves rdar://151780437
2025-05-29 13:33:36 -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
Steven Wu 3c81c1ca9f [Caching] Remove CASFS clang module implemenation
Remove the CASFS based clang module implemenation as it is not longer
used.
2025-05-14 09:35:03 -07:00
Artem Chikin d1adc24bbc Merge pull request #81415 from artemcm/CXXInteropDarwinCycleFix
[Dependency Scanning][C++Interop] Do not query `CxxStdlib` Swift overlay for textual modules which were not built with c++interop
2025-05-12 09:08:37 -07:00
Artem Chikin 94898aabf5 [Dependency Scanning][C++Interop] Do not query 'CxxStdlib' Swift overlay for textual modules which were not built with c++interop
When we discover a textual module dependency which is a module which was not originally built from source using C++ interop (specifying '-formal-cxx-interoperability-mode=off'), avoid looking up the C++ standard library Swift overlay for it. This is required for the case of the 'Darwin' module, for example, which includes headers which map to C++ stdlib headers when the compiler is operating in C++ interop mode, but the C++ standard library Swift overlay module itself depends on 'Darwin', which results in a cycle. To resolve such situations, we can rely on the fact that Swift textual interfaces of modules which were not built with C++ interop must be able to build without importing the C++ standard library Swift overlay, so we avoid specifying it as a dependency for such modules.

The primary source module, as well as Swift textual module dependencies which *were* built with C++ interop will continue getting a direct depedency of the 'CxxStdlib' Swift module.

Resolves rdar://150222155
2025-05-09 13:00:14 -07:00
Artem Chikin 4b26a3d10a [Dependency Scanning] Emit a detailed error diagnostic on Clang module variant discovery
In expectation, this should never happen. Such a situation means that within the same scanning action, Clang Dependency Scanner has produced two different variants of the same module. This is not supposed to happen, but we are currently hunting down the rare cases where it does, seemingly due to differences in Clang Scanner direct by-name queries and transitive header lookup queries.
2025-05-06 08:55:57 -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 04015fef77 [Dependency Scanning] Adopt new clang scanner API to place stable modules into an SDK-specific module cache 2025-03-19 10:43:42 -06: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 148fb369fe [Dependency Scanning] Unique collected cross-import overlay files with a set
Resolves rdar://146141228
2025-03-05 15:13:07 -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
Qiongsi Wu 69e88b176a Removing unused functions. 2025-02-12 20:19:39 -08:00
Qiongsi Wu 9a5a83ad60 Modify ModuleDependencyInfo so we can set swift interface module output paths consistently and avoid const_casts. 2025-02-12 20:19:39 -08:00
Qiongsi Wu 8055c1d17c Initial commit of InterfaceModuleNameExpander implmentation. All tests pass, and the unused vfs overlay is optimized. 2025-02-12 20:19:36 -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