This allows calling a C++ function with default arguments from Swift without having to explicitly specify the values of all arguments.
rdar://103975014
This is a forward-interop feature that wires up existing functionality for
synthesizing base class function calling to enable virtual function calling.
The general idea is to sythesize the pattern:
```
// C++ class:
struct S { virtual auto f() -> int { return 42; } };
// Swift User:
var s = S()
print("42: \(s.f())")
// Synthetized Swift Code:
extension S { func f() -> CInt { __synthesizedVirtualCall_f() } }
// Synthetized C/C++ Code:
auto __cxxVirtualCall_f(S *s) -> int { return s->f(); }
```
The idea here is to allow for the synthetized C++ bits from the Clang side to
handle the complexity of virtual function calling.
If a C++ type `Derived` inherits from `Base` privately, the public methods from `Base` should not be callable on an instance of `Derived`. However, C++ supports exposing such methods via a using declaration: `using MyPrivateBase::myPublicMethod;`.
MSVC started using this feature for `std::optional` which means Swift doesn't correctly import `var pointee: Pointee` for instantiations of `std::optional` on Windows. This prevents the automatic conformance to `CxxOptional` from being synthesized.
rdar://114282353 / resolves https://github.com/apple/swift/issues/68068
C++ `T& operator*()` is mapped to a Swift computed property `var pointee: T`.
Previously `var pointee` only had a getter, after this change it will also have a setter if the C++ type declares an overload of `operator*` that returns a mutable reference.
rdar://112471779
This fixes the automatic `std::unordered_map` conformance to CxxDictionary on Linux. Previously `std::unordered_map::const_iterator` was not auto-conformed to UnsafeCxxInputIterator because its `operator==` is defined on a templated base class of `const_iterator`.
rdar://105220600
Reformatting everything now that we have `llvm` namespaces. I've
separated this from the main commit to help manage merge-conflicts and
for making it a bit easier to read the mega-patch.
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.
A recent refactoring uncovered two places where we could end up
importing a C++ field declaration as a property more than once:
1. Importing the declaration context of a field in C++ mode can then
go import all of the fields. In such a case, check that the field
we're importing didn't happen already, and bail out early if it did.
This is common practice in the Clang importer but wasn't happening here.
2. One caller to the function that imported a field from a C++ base
class into its inheriting class (as a computed property) wasn't
checking the cache, and therefore created a redundant version.
Fix both issues.
The Clang importer's Clang instance may be configured with a different (higher)
OS version than the compilation target itself in order to be able to load
pre-compiled Clang modules that are aligned with the broader SDK, and match the
SDK deployment target against which Swift modules are also built. In this case,
we must use the Swift compiler's OS version triple in order to generate the
binary as-requested.
This change makes 'ClangImporter' 'Implementation' keep track of a distinct
'TargetInfo' and 'CodeGenOpts' containers that are meant to be used by clients
in IRGen. When '-clang-target' is not set, they are defined to be copies of the
'ClangImporter's built-in module-loading Clang instance. When '-clang-target' is
set, they are configured with the Swift compilation's target triple and OS
version (but otherwise identical) instead. To distinguish IRGen clients from
module loading clients, 'getModuleAvailabilityTarget' is added for module
loading clients of 'ClangImporter'.
The notion of using a different triple for loading Clang modules arises for the
following reason:
- Swift is able to load Swift modules built against a different target triple
than the source module that is being compiled. Swift relies on availability
annotations on the API within the loaded modules to ensure that compilation
for the current target only uses appropriately-available API from its
dependencies.
- Clang, in contrast, requires that compilation only ever load modules (.pcm)
that are precisely aligned to the current source compilation. Because the
target triple (OS version in particular) between Swift source compilation and
Swift dependency module compilation may differ, this would otherwise result in
builtin multiple copies of the same Clang module, against different OS
versions, once for each different triple in the build graph.
Instead, with Explicitly-Built Modules, Swift sets a '-clang-target' argument
that ensures that all Clang modules participating in the build are built against
the SDK deployment target, matching the Swift modules in the SDK, which allows
them to expose a maximally-available API surface as required by
potentially-depending Swift modules' target OS version.
--------------------------------------------
For example:
Suppose we are building a source module 'Foo', targeting 'macosx10.0', using an
SDK with a deployment target of 'macosx12.0'. Swift modules in said SDK will be
built for 'macosx12.0' (as hard-coded in their textual interfaces), meaning they
may reference symbols expected to be present in dependency Clang modules at that
target OS version.
Suppose the source module 'Foo' depends on Swift module 'Bar', which then
depends on Clang module `Baz`. 'Bar' must be built targeting 'macosx12.0'
(SDK-matching deployment target is hard-coded into its textual interface). Which
means that 'Bar' expects 'Baz' to expose symbols that may only be available when
targeting at least 'macosx12.0'. e.g. 'Baz' may have symbols guarded with
'__MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_12_0'. For this reason, we use
'-clang-target' to ensure 'Baz' is built targeting 'macosx12.0', and can be
loaded by both 'Foo' and 'Bar'.
As a result, we cannot direclty use the Clang instance's target triple here and
must check if we need to instead use the triple of the Swift compiler instance.
Resolves rdar://109228963
If two different C++ structs have methods with the same name, both annotated with `SWIFT_COMPUTED_PROPERTY`, ClangImporter previously confused them when one of the structs referenced the other struct.
rdar://108990490 / resolves https://github.com/apple/swift/issues/65675
If a templated C++ class declares an operator as a member function, and is instantiated using a typedef or a using-decl on the C++ side, it previously could not be conformed to a Swift protocol that requires the operator function despite matching signatures.
This was due to a Swift name lookup issue: operators, unlike regular member functions, are found by doing an unqualified lookup. Since C++ class template specializations and their members are not added to `SwiftLookupTable`, when doing qualified lookup members are searched by looking at all of the members of the specialization and choosing the ones with matching names. With unqualified lookup, we cannot rely on knowing the right specialization and need to search for all the operators in a given module.
This change adds synthesized operator thunks to `SwiftLookupTable` to make them discoverable by unqualified lookup.
When importing a C++ struct that contains two methods that only differ in const-ness, we append `Mutating` to the name of the non-const method to make it possible to call from Swift unambiguously.
Unfortunately that logic was dependent on the order in which we import methods of a class: the `Mutating` suffix was added when another method with the same name was already imported.
This caused lookup failures, and the behavior was incorrect when the pair of methods return instances of an unsafe type: the const overload was renamed as `Unsafe` properly, but the non-const overload was not renamed.
If an operator is declared as a method of a templated class, we were failing to look it up during auto-conformance to `UnsafeCxxInputIterator`.
This fixes `Interop/Cxx/stdlib/use-std-map.swift` on Ubuntu.
rdar://102420290
`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
When an anonymous enum is imported, its imported name is under some
circumstances derived from the type that it is backed by.
NS_REFINED_FOR_SWIFT is a macro that produces a __attribute__((swift_private))
that when attached to a declaration, the imported name of this
declaration should have two underscores prepended. When the name
anonymous enum is derived from another declaration, and said declaration
does not have the same swift private attribute, the __ is dropped. This
patch fixes this.
Instead of having out parameters for a couple of flags, create a small
struct with the type and the flags and return that struct inside the
Optional of importParameterType.
Additionally change the naming of some variables to make the function
and method code more similar.
Adapt the helper for figuring out parameter types for functions with the
code exclusive for figuring out method parameters. This includes special
code for handling dictionary subscripts, error parameters and completion
handlers.
The function parameters behaviour should not be modified, since in order
to import function parameters all of the new pieces of code should be
skipped following the value of the flags passed into the helper.
For method parameters, there is extensive changes, specially in the
cases of importing Obj-C++ methods that use C++ types, which were
supported for functions, but not so much for methods.
Extract a helper method `importParameterType` from the
`importFunctionParameterList` code. This new helper only deals with
function parameters, but the final intention is that it will be shared
code with the code that import method parameters.
The only functional difference introduced is that before, some of the
branches will not have added an extra diagnostic about parameters
failing to import, while this version adds those diagnostics
consistently for any case.
This change tweaks the 'GlobalModuleDependenciesCache', which persists across scanner invocations with the same 'DependencyScanningTool' to no longer cache discovered Clang modules.
Doing so felt like a premature optimization, and we should instead attempt to share as much state as possible by keeping around the actual Clang scanner's state, which performs its own caching. Caching discovered dependencies both in the Clang scanner instance, and in our own cache is much more error-prone - the Clang scanner has a richer context for what is okay and not okay to cache/re-use.
Instead, we still cache discovered Clang dependencies *within* a given scan, since those are discovered using a common Clang scanner instance and should be safe to keep for the duration of the scan.
This change should make it simpler to pin down the core functionality and correctness of the scanner.
Once we turn our attention to the scanner's performance, we can revisit this strategy and optimize the caching behaviour.
Calling `NominalTypeDecl::lookupDirect` triggers deserialization of Swift extensions for the type. `ClangRecordMemberLookup` shouldn't assume it is allowed to deserialize Swift extensions for the given C++ type: there might be extensions which reference the module that is currently being imported, which causes circular request dependency errors.
This teaches ClangImporter to synthesize conformances of C++ iterator types to `UnsafeCxxInputIterator` protocol from the `Cxx` module.
We consider a C++ type to be an iterator if it defines a subtype (usually a typedef or a using decl) called `iterator_category` that inherits from `std::input_iterator_tag`.
rdar://96235368
This reduces the specialization limit from 10000 to 1000 to prevent Swift from failing to import libstdc++ due to `std::_Index_tuple` being defined recursively.
This also adds a diagnostic to let the user know why a template instantiation wasn't imported.
rdar://96324175
`ImportDecl.cpp` contained 10k+ lines of code, which caused slowdowns in incremental compilation and while editing the code in the IDE.
This change extracts a chunk of largely self-contained decl synthesis logic into a separate file.
When ClangImporter::Implementation::inferDefaultArgument processes
func/method arguments as part of omitNeedlessWordsInFunctionName it
processes information about how the typenames for the parameters related
to the parameter names to form a parameter names list. The parameter
names list is used to determine if the argument label for a function
should be clipped based on the typename. So for example a type like
NSOrderedCollectionDifferenceCalculationOptions would cause a label
ending with "Options" to get clipped so that for instance "withOptions"
becomes simply "with".
Unfortunately in the context of C++-Interop, the typename for the
parameter often resolves to what the type backing the typedef or enum is
and not the actual name of the typedef
(so `typedef NSUInteger NSOrderedCollectionDifferenceCalculationOptions`
resolves to a name of NSUInteger rather than
NSOrderedCollectionDifferenceCalculationOptions).
This patch seeks to collect a bit more information when processing
NS_OPTIONS typedefs and providing that to the calling
omitNeedlessWordsInFunctionName to handle more inteligently.
In practice this fixes anywhere in Foundatio where
`withOptions: NSOrderedCollectionDifferenceCalculationOptions` is used.
`InclusionDirective` was changed in llvm/llvm-project
d79ad2f1dbc2db63121620f55d6cfa915f2733ac to pass an
`Optional<FileEntryRef>` rather than a `FileEntry *`. Update overrides
in Swift to use the new API.