This fixes a crash in SILGen when calling a C++ subscript that has an unnamed parameter from Swift.
The parameters from a C++ `operator[]` get carried over to the synthesized Swift subscript. If the Swift parameter has no name, there is no way to refer to it in SIL. However, the synthesized subscript accessor needs to pass this parameter to C++.
This change makes sure that we give a name to the Swift parameter if there isn't already a name on the C++ side.
rdar://83163841
This allows calling a C++ function with default arguments from Swift without having to explicitly specify the values of all arguments.
rdar://103975014
Previously, `friend` operators declared in C++ classes were added to the lookup table when the class is being imported.
The operators were added to the wrong lookup table if the class is declared in a C++ namespace. Since a namespace can span across multiple Clang modules, its contents should be added to a translation unit level lookup table, not to a module level lookup table.
This change makes sure we add `friend` operators to the lookup table earlier, when we are actually building the lookup table. Note that this is not possible for class template instantiations, because those are instantiated later, so for templates we still handle `friend` operators when importing the instantiation.
rdar://116349899
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
If a C++ struct defines multiple overloads of `operator*`, avoid synthesizing multiple `var pointee: Pointee` properties, since that would introduce name resolution ambiguity. Instead, pick one of the const overloads and synthesize a single `pointee` property.
This is required for `std::optional` support.
These operators return `Void` in Swift, let's drop the return type of these operators when importing them from C++.
This is needed for the upcoming `UnsafeCxxRandomAccessIterator` protocol: if a protocol declares `func +=` returning `Void`, but the implementation non-`Void`, that causes a typechecker error.
* Update ImportDecl to handle Friend functions inside of recrods
* Add tests and update comment
* Undo unnecessary lines, format
* Clean up and fix tests
* New approach
* Only import valid friend functions for now
* Re-add == func to get Equatable conformance
* Remove requirement that friend is a function
If the IR representation of a C++ function takes an `SRet` parameter instead of a return value, Swift needs to wrap the corresponding argument with `sret(...)` on call site.
This fixes SILOptimizer crashes on arm64.
rdar://92963081
We saw a test case failing when 2 records contain the same operator. This occurs because when the first operator is called, we import the record associated with that operator but we also import the _function_ for the 2nd record. So if we have 2 records `Foo` and `Bar` and both implement `operator-`, after calling `Foo`'s `operator-` we would have imported
1. `Foo`
2. `Foo.operator-`
3. `Bar.operator-`
Then when we call `Bar.operator-` we try importing `Bar` record & then import the operator again. So that ends up with
1. `Foo`
2. `Foo.operator-`
3. `Bar.operator-`
4. `Bar`
5. `Bar.operator-`
which causes there to be 2 imports of the same operator (`FuncDecl`)
This patch checks to see if the `FuncDecl` was previously imported and returns early if it has been
Thanks @egorzhdan and @zoecarver for helping me debug this one :p
C++ pre-increment operator `T& T::operator++()` is mapped into a non-mutating function `successor() -> Self`.
The naming matches existing functions for `UnsafePointer`/`UnsafeMutablePointer`.
The purpose of this is to be used for iterator bridging: C++ requires iterators to define a pre-increment operator (https://en.cppreference.com/w/cpp/named_req/Iterator), which Swift will use to iterate over C++ sequences and collections.
C++ iterator dereference operator is mapped to a Swift computed property called `pointee`.
For example:
```cpp
struct ConstIterator {
// ...
const int &operator*() const { /* ... */ }
};
```
is imported as
```swift
struct ConstIterator {
var pointee: Int32 { get }
@available(*, unavailable, message: "use .pointee property")
func __operatorStar() -> UnsafePointer<Int32>
}
```
This does not include subscript operators.
Before this is re-enabled operators need to be re-implemented. Right now they are the source of a lot of bugs. They cause frequent crashes and mis compiles. Also, templated operators insert a lot of names into global lookup which causes problems.
They also don't work on Windows.
* [cxx-interop] fix std::string::push_back by fixing mapping between clang/swift self/this type for cxx methods
* cleanup
* Fix unit test
* XFail test: operators/member-inline on linux-android
* add `C++` in expandExternalSignatureTypes comment
* Fix rebase
* Fix mapping issue in externalizeArguments
* Improve cxx_interop_ir test regex
This enables the majority of the operator tests on Windows as these now
pass. However, we cannot enable all of the tests, a few of them crash
due to invalid parameter ordering due to bugs in IRGen with C++ interop.
This change makes ClangImporter import some C++ member functions as non-mutating, given that they satisfy two requirements:
* the function itself is marked as `const`
* the parent struct doesn't contain any `mutable` members
`get` accessors of subscript operators are now also imported as non-mutating if the C++ `operator[]` satisfies the requirements above.
Fixes SR-12795.
This builds on top of the work of Egor Zhdan. It implements
`T operator[]` and does so largely by taking a path very much like the
`const T &operator[]` path.
This change adds support for calling `operator()` from Swift code.
As the C++ interop manifesto describes, `operator()` is imported into Swift as `callAsFunction`.
Adding integers is a commutative operation meaning the old tests would
fail to detect an error if the arguments were passed in the wrong order.
Testing inline member operators using subtraction ensures that arguments
are passed in the correct order.
This adds support to `ClangImporter` to import C++ member function operators as static methods into Swift, which is part of SR-12748.
The left-hand-side operand, which gets passed as the `this` pointer to the C++ function is represented as an additional first parameter in the Swift method. It gets mapped back in SILGen.
Two of the tests are disabled on Windows because we can't yet call member functions correctly on Windows (SR-13129).