It looks like there's another problem converting Int -> Int64 on Windows. This test doesn't touch integer conversions, so I updated the tests to work around it.
Dependent types are going to be very hard to support, especially in complex cases. This PR adds a workaround that people can use: `Any`. This requires manual type casting, but it does work.
This is important because the specialized template will be imported as `inout int` (for example) and we must make sure to match the signature.
Updates tests based on this and fixes a few tests that started failing after daceecfc75.
Adds tests for using std-vector and some other interesting types.
This patch fixes four mis conceptions that the compiler was previously making:
1. Implicit destructors have no side effects. (Yes, this means we were not cleaning up some objects.)
2. Implicit destructors have bodies. (Technically they do, but the body doesn't include CallExprs that they make when lowered to IR.)
3. Functions other than methods can be uninstantiated templates.
4. Uninstantiated templates may have executable code. (I.e., we can never take the fast path.)
And makes sure that we visit the destructor of any VarDecl (including parameters).
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.
If possible, add imported members to the StructDecl's LookupTable rather than adding them directly as members. This will fix the issues with ordering that #39436 poorly attempted to solve during IRGen.
This also allows us to break out most of the test changes from #39436.
If a defaulted template type parameter is not used in the function's
signature, don't create a corresponding generic argument for that
template type. This allows us to call function templates with defaulted
template type parameters. This is very common in the standard library
for things like enable_if which is used to disable various
functions/overloads with SFINAE.
The biggest part of this change is going forward not all function
templates will be imported as generic functions in Swift. This should
work OK but we may discover there was some logic which only looked for
generic function when dealing with function templates.
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.
Lazily instantiate class template members. This means we no longer
reject some programs that clang accepts, such as the following:
```
template<class T> struct Foo { void fail(T value) { value.fail(); } };
using Bar = Foo<int>;
```
The above program will not error so long as `Bar::fail` isn't called.
(Previously, we'd fail to import `Bar`.)
If a template specialization is more than 8 types deep, bail.
In future we could make this number (much) greater than 8 but first
we'll need to somehow make instantiating these types much fater.
Currently, I think there is some exponential type behavior happening so
this is super slow.
C++ namespaces are module-independent, but enums are owned by their module's in Swift. So, to prevent declaring two enums with the same name, this patch implements a new approach to namespaces: enums with extensions.
Here's an example:
```
// Module A
namespace N { void test1(); }
// Module B
namespace N { void test2(); }
// __ObjC module
enum N { }
// Swift module A
extension N { func test1() }
// Swift module B
extension N { func test1() }
```
Thanks to @gribozavr for the great idea.
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>
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.