This is phase-1 of switching from llvm::Optional to std::optional in the
next rebranch. llvm::Optional was removed from upstream LLVM, so we need
to migrate off rather soon. On Darwin, std::optional, and llvm::Optional
have the same layout, so we don't need to be as concerned about ABI
beyond the name mangling. `llvm::Optional` is only returned from one
function in
```
getStandardTypeSubst(StringRef TypeName,
bool allowConcurrencyManglings);
```
It's the return value, so it should not impact the mangling of the
function, and the layout is the same as `std::optional`, so it should be
mostly okay. This function doesn't appear to have users, and the ABI was
already broken 2 years ago for concurrency and no one seemed to notice
so this should be "okay".
I'm doing the migration incrementally so that folks working on main can
cherry-pick back to the release/5.9 branch. Once 5.9 is done and locked
away, then we can go through and finish the replacement. Since `None`
and `Optional` show up in contexts where they are not `llvm::None` and
`llvm::Optional`, I'm preparing the work now by going through and
removing the namespace unwrapping and making the `llvm` namespace
explicit. This should make it fairly mechanical to go through and
replace llvm::Optional with std::optional, and llvm::None with
std::nullopt. It's also a change that can be brought onto the
release/5.9 with minimal impact. This should be an NFC change.
- Ensure that no callbacks are called when either of these mutexes are held:
- `SwiftASTConsumer::CancellationRequestCallbackAndIsCancelledMtx`
- `ASTBuildOperation::DependencyStampsMtx`
- Exception: We allow calls to `getBuferStamp` because that doesn’t claim any locks)
- No change was necessary here
- `ASTBuildOperation::ConsumersAndResultMtx`
- `ASTBuildOperation::CacheMtx`
- No change was necessary here
- `ASTBuildOperation::ScheduledConsumersMtx`
- Make sure we always inform the consumers asynchronously, even if the operation was already cancelled when the consumer got enqueued by introducing `ConsumerNotificationQueue`
- Ensure that all callbacks to `SwiftASTConsumer` (i.e. `requestCancellation` and `handlePrimaryAST`, `failed`, `cancelled`) are performed asyncronously from a queue to avoid deadlocks
rdar://110357502
Make a single 'PluginRegistry' and share it between SwiftASTManager,
IDEInspectionInstance, and CompileInstance. And inject the plugin
registry to ASTContext right after 'CompilerInstance.setup()'
That way, all sema-capable ASTContext in SourceKit share a single
PluginRegistry.
`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
#58786 (rdar://93030932) was failing because the `swift-frontend` invocations passed a `swiftExecutablePath` to `Invocation.parseArgs`. This caused the `ClangImporter` instance to point to a `clang` binary next to the `swift-frontend` executable while SourceKit used PATH to find `clang`. The clang executable next to `swift-frontend` doesn’t actually exist because `clang` lives in `llvm-linux-aarch64/bin` and `swift-frontend` lives in `swift-linux-aarch64/bin`.
So some checks for a minimum clang verison failed for the normal build (because the executable doesn’t actually exists) while they pass during the SourceKit build (which used `clang` from `PATH`). This in turn caused the `outline-atomics` to be enabled to the SourceKit clang compiler arguments but not the clang compiler arguments for a normal build and thus resulted in two separate module cache directories (which includes the enabled features in the module directory hash).
To fix this issue, also set the swift executable path for compiler invocations created from SourceKit.
Fixes#58786 (rdar://93030932)
Enqueuing `SwiftASTConsumer`s might be expensive because `getBuildOperationForConsumer` consults the file system. Since all results from the AST build are processed asynchronously anyway, there’s no need to perform the enqueuing synchronously.
rdar://86289703
Previously, `SwiftASTManager` and `SlowRequestSimulator` maintained their own list of in-progress cancellation tokens. With code completion cancellation coming up, there would need to be yet another place to track in-progress requests, so let’s centralize it.
While at it, also support cancelling requests before they are scheduled, eliminating the need for a `sleep` in a test case.
The current implementaiton leaks tiny amounts of memory if a request is cancelled after if finishes. I think this is fine because it is a pretty nieche case and the leaked memory is pretty small (a `std::map` entry pointing to a `std::function` + `bool`). Alternatively, we could require the client to always dispose of the cancellation token manually.
The key changes here are
- To keep track of cancellation tokens for all `ScheduledConsumer`s in `SwiftASTManager`
- Generate unique request handles for all incoming requests (`create_request_handle `), use these request handles as cancellation tokens and return them from the `sourcekitd_send_request` methods
- Implement cancellation with `sourcekitd_cancel_request` as the entry point and `SwiftASTManager::cancelASTConsumer` as the termination point
Everything else is just plumbing the cancellation token through the various abstraction layers.
rdar://83391505
This commit refactors the way ASTs are being built in SourceKit and how `SwiftASTConsumer`s are served by the built ASTs. `SwiftASTManager.h` should give an overview of the new design.
This commit does not change the cancellation paradigm in SourceKit (yet). That is, subsequent requests with the same `OncePerASTToken` still cancel previous requests with the same token. But while previously, we were only able to cancel requests that haven’t started an AST build yet, we can now also cancel the AST build of the to-be-cancelled requests.
With this change in place, we can start looking into explicit cancellation of requests or other cancellation paradigms.
SwiftSourceInfo files provide source location information for decls coming from
loaded modules. For most IDE use cases it either has an undesirable impact on
performance with no benefit (code completion), results in stale locations being
used instead of more up-to-date indexer locations (cursor info), or has no
observable effect (live diagnostics, which are filtered to just those with a
location in the primary file).
For non-IDE clients of SourceKit though, cursor info providing declaration
locations for symbols from other modules is useful, so add a global
configuration option (and a new request to set it) to control whether
.swiftsourceinfo files are loaded or not based on use case (they are loaded by
default).
The invocation options are not an appropriate place to put this state,
since it can change between requests. This moves it to the editor
document, allowing us to change the specific VFS instance without
causing a rebuild (unless the contents/timestamps for a dependency
change).
When the server shuts down we may still have outstanding async work to
build an AST, so use a shared_ptr + weak_ptr instead of unique_ptr +
unowned references.
Stop parsing frontend arguments directly and use the driver instead. The
most intersting part of this change is that it forces us to consider
whether our compiler invocation will have inputs or not. We have
several kinds of requests that need to create a compiler instance, but
not parse any inputs (interface-generation, doc-info, and indexing when
operating on a module instead of source files).
Incidentally, add an error when trying to do doc-info on multiple source
files. This was already very broken (assertion failures and bogus source
locations), so add an error for it.
rdar://problem/17897287
... and add a few basic statistics about the number of requests, ASTs
built, etc. The Statistic type is loosely based on the one from LLVM,
but suitable for using without DEBUG macros and using SourceKit UIdents
to identify the statistic. The easiest way to add a new statistic is to
add it to SwiftStatistics.def in the SwiftLangSupport.
Cursor info requires access to the underlying AST, which is not
thread-safe. This manifest as crashes when performing concurrent
cursor-info requests on the same generated interface. We already
prevented concurrent cursor-infos on regular Swift files by using the
ASTManager, but generated interfaces use the InterfaceGenContext which
may use either an ASTUnit or its own internal CompilerInstance.
rdar://problem/27311624
The code goes into its own sub-tree under 'tools' but tests go under 'test',
so that running 'check-swift' will also run all the SourceKit tests.
SourceKit is disabled on non-darwin platforms.