`CxxRecordSemanticsKind::ExplicitlyUnsafe` and `CxxRecordSemanticsKind::UnsafePointerMember` were never directly used, and those do not indicate semantics: they indicate safety of the type when used from Swift, which should be handled by another request `IsSafeUseOfCxxDecl` instead of `CxxRecordSemantics`.
Having `ExplicitlyUnsafe` and `UnsafePointerMember` as semantics indicators was problematic, for instance, for types that are move-only and store a pointer at the same time. Swift allowed the usage of these types (under the rules for `UnsafePointerMember` types) when move-only types are disabled, and did not apply the move-only attribute on such types when move-only types are enabled.
rdar://110644300
When a default constructor is declared, but does not have a body because it is defaulted (`= default;`), Swift did not emit the IR for it. This was causing linker error for types such as `std::map` in libstdc++ when someone tried to initialize such types from Swift.
rdar://110638499 / resolves https://github.com/apple/swift/issues/61412
When determining whether a C++ method is safe to be imported, we look at its return type to see if it stores any pointers in its fields.
If the type is templated, we might not have its definition available yet. Unfortunately we cannot instantiate it on the spot, since the Clang AST would be read and written at the same time.
Let's stay on the safe side and treat such methods as unsafe.
rdar://107609381
C++ types that store pointers as fields are treated as unsafe in Swift. Types that store other types that in turn store pointers are also treated as unsafe.
Types that store raw C++ iterators are also treated as unsafe in Swift. However, a type that stores another type that stores a raw iterator was previously imported as safe. This change fixes that.
rdar://105493479
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.
This was discovered during interop adoption in SwiftCompilerSources.
```
/Volumes/Projects/swift/swift/include/swift/SIL/SILNode.h:180:5 <Spelling=/Volumes/Projects/swift/swift/include/swift/SIL/SILNode.h:171:3>: while adding SwiftName lookup table entries for clang declaration 'swift::SILNode::SharedUInt8Fields::(anonymous)'
```
Calling `StructDecl::lookupDirect` with an operator identifier (e.g. `==`) previously returned no results. This happened because the underlying C++ operator function was added to the lookup table with an underscored name (e.g. `__operatorEqualEqual`), and the synthesized function was not added to the lookup table at all. Lookup should find the synthesized decl, since that is what Swift code will call.
This fixes a typechecker error when trying to conform a C++ struct that defines an operator to a Swift protocol with an operator requirement (e.g. `Equatable`).
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
Restructure the `visualc` module into `vcruntime` in order to help
expose the various components (SAL, vcruntime, ucrt, corecrt, STL) for C++
modularization. Include the `stdint.h` textually to deal with
redefinition of types in clang resources and MSVC.
If a C++ method returns a pointer and is not annotated with `returns_nonnull`, ClangImporter imports its return type as implicitly unwrapped optional `UnsafePointer<T>!`. This happens, for example, for `begin()`/`end()` methods of C++ collection types.
We would like to be able to conform C++ collections to `Swift.Sequence`/`Swift.Collection`/... To make this work, we create Swift protocols that require `func begin() -> RawIterator` and `func end() -> RawIterator` where `RawIterator` is an associated type.
The problem is that currently if `RawIterator` is `UnsafePointer<T>?`, `begin()`/`end()` methods that return an implicitly unwrapped optional `UnsafePointer<T>!` won't satisfy the requirements. This change fixes that.
Previously, the clang importer marked all const methods as mutating whenever a C++ record had mutable fields. This change allows overriding this behavior by using the "nonmutating" swift_attr attribute.
Fixes SR-15907.
When we look up a name directly, make sure we provide a scope, this is required when C++ interop is enabled.
This issue was exposed when we look up if an NSString is hashable. There is a special case for classes that inherit from NSObject, but we didn't see that, because we couldn't find NSObject (because lookup failed).
The Clang Importer when C++ interop is not enabled, disambigate an Obj-C
class and protocol that are named the same by appending `Protocol` to
the protocol. This was not happening when C++ interop was enabled, but
should also apply to Obj-C++ modules.
The fix is providing an starting scope for the search, which the C++
name lookup need to actually find the similarly named counterpart.
Includes a test to avoid this problem creeping in again, and locally it
did not break any other tests.
There are three major changes here:
1. The addition of "SILFunctionTypeRepresentation::CXXMethod".
2. C++ methods are imported with their members *last*. Then the arguments are switched when emitting the IR for an application of the function.
3. Clang decls are now marked as foreign witnesses.
These are all steps towards being able to have C++ protocol conformance.
This change teaches ClangImporter to import C++ methods marked with `__attribute__((__swift_attr__("mutating")))` as mutating in Swift. This is useful, for example, when a method mutates `this` despite being `const` in C++ (e.g. via `const_cast`).
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.
If we have a C++ record decl that's invalid (because of a deleted
destructor or copy constructor), bail before we import any of its
members or cache the decl. This way, we don't accidentally import any
"nested" decls.
Fail correctly if we can't import a shadow decl properly. We can
probably support this in the future, but right now, it's more important
that we don't crash while importing.
The pattern:
struct X { friend struct Y; }; struct Y {};
is fairly common. But before this commit we would crash while attempting
to add "Y" as a child of "X". This commit simply checks if the child
record is a declaration or definition. If the former, it bails (and the
"child" record will be imported where it's defined).
Rather than skipping non-definitions, we should just check whether we've
already seen this decl. This not only fixes the specific problem with
class templates but also is a more general fix for other sub decls.
This patch adds support for custom C++ destructors. The most notable thing here, I think, is that this is the first place a struct type has a custom destructor. I suspect with more code we will expose a few places where optimization passes need to be fixed to account for this.
One of many patches to fix SR-12797.
It is not completely uncommon for a record to get imported while
importing it's members (for example, if the member points back to the
parent record). In this case, simply use the already-imported record.
This should improve performance but also prevent an error where a member
accidentally had two parents.
This patch also moves around some of the member import/add logic to
allow for the above "optimization."
The C++ interop modules require C++ support. Explicitly require C++ as
a feature when building these modules. This has no impact on the
changes as all the tests enable C++ already.