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.
This PR makes it possible to instantiate C++ class templates from Swift. Given a C++ header:
```c++
// C++ module `ClassTemplates`
template<class T>
struct MagicWrapper {
T t;
};
struct MagicNumber {};
```
it is now possible to write in Swift:
```swift
import ClassTemplates
func x() -> MagicWrapper<MagicNumber> {
return MagicWrapper<MagicNumber>()
}
```
This is achieved by importing C++ class templates as generic structs, and then when Swift type checker calls `applyGenericArguments` we detect when the generic struct is backed by the C++ class template and call Clang to instantiate the template. In order to make it possible to put class instantiations such as `MagicWrapper<MagicNumber>` into Swift signatures, we have created a new field in `StructDecl` named `TemplateInstantiationType` where the typechecker stores the `BoundGenericType` which we serialize. Deserializer then notices that the `BoundGenericType` is actually a C++ class template and performs the instantiation logic.
Depends on https://github.com/apple/swift/pull/33420.
Progress towards https://bugs.swift.org/browse/SR-13261.
Fixes https://bugs.swift.org/browse/SR-13775.
Co-authored-by: Dmitri Gribenko <gribozavr@gmail.com>
Co-authored-by: Rosica Dejanovska <rosica@google.com>
Clang will properly mark the C++ `this` parameter as `nonnull` and
`dereferenceable(1)` as per the C++ specification. Update the tests to
accept the newer attributes.
Currently the following code doesn't work when `callConstructor()` is called from Swift:
```cc
inline int increment(int value) {
return value + 1;
}
struct Incrementor {
int incrementee;
Incrementor(int value) : incrementee(increment(value)) {}
}
int callConstructor(int value) {
return Incrementor(value).incrementee;
}
```
The issue is that we don't generate `IR` for the `increment()` function when it's only called from a constructor or a method.
Swift is aware of the existence of `increment()` and we see it in `IR` as `declare incrementEi`, however, as we don't to emit a definition, we get the following error:
```
Incrementor::Incrementor(int): error: undefined reference to 'increment(int)'
```
This PR fixes this by visiting constructors and methods in `IRGen` and calling `HandleTopLevelDecl()` with all used declarations, which results in emitting definitions for the used declarations.
Co-authored-by: Marcel Hlopko <hlopko@google.com>
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."
Add an convert to the new `target-swiftxx-frontend` substitution in lit
to control the C++ interop enabling in Swift. This allows for a single
site which will enable control of both an overridden standard (for
testing multiple C++ standards) and simplify writing tests.
Now that the integral constants are being materialized when importing
`constexpr` from C++, we can avoid the need for the optimizer to inline
the value. Remove this workaround.
Restore the explicit C++ standard for these tests as the C++ compiler
invocation on Darwin uses the system compiler rather than the just built
clang, which may be sufficiently different to have different default
standards.
This will be cleaned up with the next change to introduce a new
`%target-clangxx` to control the C++ standard.
Do not override the C++ standard explicitly when running the tests.
This will eventually be useful in allowing tests to run against
different C++ standards.
* Fix two issues with the SwiftGlibc module map.
The issues are:
- Today, some submodules in `SwiftGlibc` fail to provide definitions that
they should contain. As a consequence, Swift fails to import some code
that compiles correctly with standalone Clang. As just one example,
including `signal.h` should make the type `pid_t` available, but it
currently does not.
- `SwiftGlibc` is not compatible with the libc++ module map. Trying to
include libc++ headers in a C++ module imported into Swift results in an
error message about cyclic dependencies.
This change fixes both of these issues by making it so that `SwiftGlibc`
no actually longer defines a module map for the glibc headers but merely makes
all of the symbols from those headers available in a module that can be
imported into Swift. C / Objective-C / C++ code, on the other hand, will now
include the glibc headers texually.
For more context on the two issues and this fix, see this forum
discussion:
https://forums.swift.org/t/problems-with-swiftglibc-and-proposed-fix/37594
This change only modifies `glibc.modulemap.gyb` for the time being but
leaves `bionic.modulemap.gyb` and `libc-openbsd.modulemap.gyb` unchanged. The
intent is to fix these in the same way, but it will be easier to do this
in separate PRs that can be tested individually.
Co-authored-by: zoecarver <z.zoelec2@gmail.com>
Co-authored-by: Marcel Hlopko <hlopko@google.com>
If a static variable can be evaluated at compile time, create an
accessor using that value. This means static variables will always be
inlined and removed.
Note: currently this only works with numeric types.
This synchronizes the C/C++ standard that Swift uses for the clang
importer with the defaults of the clang compiler.
The default for the C standard remains the same at `gnu11`. However, if
clang was built with a different default C standard, that will be
preferred.
The default for the C++ standard is moved to C++14. Although this is a
reduced version, it matches what the current clang compiler defaults to.
Additionally, if the user built clang with a different C++ standard,
that standard would be preferred.
Although the C++ support is a bit more conservative, the idea is that we
can be certain that the clang version fully supports this standard as it
it the default version for clang.
The test change made here replaces the use of `auto` type parameters to
templates which is a C++17 feature. Reduce the example to a C++14
equivalent.
The clang version seems to behave differently in preventing the
synthesis of the constexpr value. This persists into the newer clang
releases as well. This is reasonable as the value does not need to be
exported necessarily and users will be able to materialize the value.
We use the optimizer to ensure that the value is inlined.
This also repairs the C++ interop tests on Windows with a newer C++
runtime from Microsoft.
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.
Simply treat scoped enums as (pre-existing) "non frozen enums". C++
scoped enums are actually imported as Swift enums (unlike other enums)
and no global variables need be created (given their "scoped" nature).
Clang types need special treatment because multiple Clang modules can contain the same type declarations from a textually included header, but not all of these modules may be visible.
This fixes
https://bugs.swift.org/browse/SR-13032
The newly added test breaks without this fix.