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.
This fixes an error that occurred when trying to use the subscript on an instance `std::map`:
```
error: cannot assign through subscript: 'map' is immutable
```
This was happening even with a mutable `std::map` instance.
`std::map::operator[]` has two overloads:
* `T& operator[]( const Key& key )`
* `T& operator[]( Key&& key )`
The second one is imported with an `inout` parameter, and we picked it as an implementation of the subscript getter because it was the last of the two overloads to get imported.
Swift does not allow subscripts with `inout` parameters. This is checked at the AST level, and those checks do not run for synthesized Swift code. This caused Swift to produce a surprising error which actually indicated that the argument of the subscript, not the instance itself, must be mutable.
rdar://100529571
Our current implementation of `func successor() -> MyType` relies on the ability to create a new instance of the type. For immortal foreign reference types, this wouldn't be reasonable to do.
rdar://100050151
Prefix operators in Swift need to be marked as `prefix func`.
For example, the lack of `prefix` attribute prevents the user from conforming a C++ type that defines `operator!` to a Swift protocol that requires `static prefix func !(obj: Self) -> Self`.
* 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>
}
```
Previously when looking up a C++ operator (e.g. `==`), `ClangImporter::Implementation::lookupValue` returned a Swift function with a generated name (e.g. `func __operatorEqualEqual`), while the caller expected the result to be a Swift operator (e.g. `func ==`).
This change makes sure that we're returning a synthesized Swift operator when looking for a C++ operator.
This fixes an assertion failure in the typechecker:
```
swift-frontend: /home/build-user/swift/lib/Sema/ConstraintSystem.cpp:1454: std::pair<Type, Type> swift::constraints::ConstraintSystem::getTypeOfReference(swift::ValueDecl *, swift::FunctionRefKind, swift::constraints::ConstraintLocatorBuilder, swift::DeclContext *): Assertion `func->isOperator() && "Lookup should only find operators"' failed.
```