This separates it from `libSwiftScan` and allows us to build this library without building much of the rest of the compiler.
Also refactor `utils/build-parser-lib` into `utils/build-tooling-libs` which builds both SwiftSyntaxParser and SwiftStaticMirror.
The Windows uses `\` as a path separator, which is not permitted within
a JSON string without escaping. This corrects the encoding of the path
separator in the emitted dependency information. This issue was found
through the swift-driver test suite.
Instead of checking that the stdlib can be loaded in a variety of places, check it when setting up the compiler instance. This required a couple more checks to avoid loading the stdlib in cases where it’s not needed.
To be able to differentiate stdlib loading failures from other setup errors, make `CompilerInstance::setup` return an error message on failure via an inout parameter. Consume that error on the call side, replacing a previous, more generic error message, adding error handling where appropriate or ignoring the error message, depending on the context.
llvm-project `ErrorHandling.h` was updated to remove std::string. This
added a new `report_fatal_error` overload taking a `const Twine &`,
removed the overload that took `const std::string &`, and updated
`fatal_error_handler_t` to use `const char *` rather than `const
std::string &`.
Fix uses of these functions to take into account these updates. Note
that without the `const std::string &` overload, passing a `std::string`
into `report_fatal_error` now results in an ambiguous match between the
`StringRef` and `Twine` overloads so we need to be explicit about one or
the other.
Doing so will allow clients to know which Swift-specific PCM arguments are already captured from the scan that first discovered this module.
SwiftDriver, in particular, will be able to use this information to avoid re-scanning a given Clang module if the initial scan was sufficient for all possible sets of PCM arguments on Swift modules that depend on said Clang module.
And only resolve cached dependencies that came from scanning actions with the same target triple.
This change means that the `GlobalModuleDependenciesCache` must be configured with a specific target triple for every scannig action, and it will only resolve previously-found dependencies from previous scannig actions using the exact same triple.
Furthermore, the `GlobalModuleDependenciesCache` separately tracks source-file-based module dependencies as those represent main Swift modules of previous scanning actions, and we must be able to resolve those regardless of the target triple.
Resolves rdar://83105455
These kinds of modules differ from `SwiftTextual` modules in that they do not have an interface and have source-files.
It is cleaner to enforce this distinction with types, instead of checking for interface optionality everywhere.
This change causes the cache to be layered with a local "cache" that wraps the global cache, which will serve as the source of truth. The local cache persists only for the duration of a given scanning action, and has a store of references to dependencies resolved as a part of the current scanning action only, while the global cache is the one that persists across scanning actions (e.g. in `DependencyScanningTool`) and stores actual module dependency info values.
Only the local cache can answer dependency lookup queries, checking current scanning action results first, before falling back to querying the global cache, with queries disambiguated by the current scannning action's search paths, ensuring we never resolve a dependency lookup query with a module info that could not be found in the current action's search paths.
This change is required because search-path disambiguation can lead to false-negatives: for example, the Clang dependency scanner may find modules relative to the compiler's path that are not on the compiler's direct search paths. While such false-negative query responses should be functionally safe, we rely on the current scanning action's results being always-present-in-the-cache for the scanner's functionality. This layering ensures that the cache use-sites remain unchanged and that we get both: preserved global state which can be queried disambiguated with the search path details, and an always-consistent local (current action) cache state.
The dependency scanner's cache persists across different queries and answering a subsequent query's module lookup with a module not in the query's search path is not correct.
For example, suppose we are looking for a Swift module `Foo` with a set of search paths `SP`.
And dependency scanner cache already contains a module `Foo`, for which we found an interface file at location `L`. If `L`∉`SP`, then we cannot re-use the cached entry because we’d be resolving the scanning query to a filesystem location that the current scanning context is not aware of.
Resolves rdar://81175942
https://github.com/apple/swift/pull/37774 (related to rdar://72480261) has made it so that the target of built clang modules (even downstream from Swift interface dependencies) can be consistent with that of the main module. This means that when building transitive Clang dependencies of the main module, they will always have a matching triple to the main module itself (ensured with `-clang-target`). This means we no longer have to report the target triple in the set of `extraPCMArgs` which encode an interface-specific requirement for building its dependencies.
Using the serialization format added in https://github.com/apple/swift/pull/37585.
- Add load/save code for the `-scan-dependencies` code-path.
- Add `libSwiftDriver` entry-points to load/store the cache of a given scanner instance.
This mechanism allows the compiler to use a backup interface file to build into a binary module when
a corresponding interface file from the SDK is failing for whatever reasons. This mechansim should be entirely opaque
to end users except several diagnostic messages communicating backup interfaces are used.
Part of rdar://77676064
This will enable users to try out the '-enable-ossa-modules' flag if their
compiler supports it and get OSSA code on all inlinable code that they use. The
idea is that this is a nice way to stage this in and get more testing.
The specific implementation is that the module interface loader:
1. Knows if enable ossa modules is enabled not to search for any compiled
modules. We always rebuild from the interface file on the system.
2. Knows that if enable ossa modules is enabled to mixin a bit into the module
interface loader cache hash to ensure that we consider the specialized ossa
compiled modules to be different than the modules in that cache from the system.
This ensures that when said flag is enabled, the user transparently gets all
their code in OSSA form from transparent libraries.
We must reset option occurences on each entry because we are handling an unrelated command-lines to those parsed before. We must do so because LLVM options parsing is done using a managed static `GlobalParser`.
Resolves rdar://75247030
Additional arguments that the compiler must pass to the Clang Importer (Clang dep scanner), incl. search paths, must come from the invocation that launched the scan in order to correctly match the specific target being scanned, instead of re-using those from a cached CompilerInstance.
The intent is two-fold:
1. This fixes a bug where we would only attempt to resolve direct dependencies as Clang modules for Swift Binary modules.
2. Ensures that we only query the presence of a Bridging Header for textual Swift modules.
Resolves rdar://73015075
This speeds up contexts where we need to resolve dependencies after the main scanning action is complete.
For example: libSwiftScan binary graph generation and cycle detection.
This is necessary because ordinarily, ModuleDependenciesCache must be queried on a per-loader basis.
For example, we first search for Swift modules with the SerializedModuleLoaderBase, at which point we check the cache for previously-found Swift modules. If cache is not hit, we search the filesystem.
Then we search for Clang moduels with the ClangLoader, at which point we check the cache for previously-found Clang modules. If cache is not hit, we search the filesystem.
This change allows to eliminate a bunch of filesystem searching in step (1) when we know we have completed the scan and no longer need to be concerned with the correctness of the cache contents.