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 is a roll-forward of https://github.com/apple/swift/pull/32950, with explicit c++17 version removed from tests. This is not needed since C++17 is the default anyway.
--
In this PR we teach `ClangImporter` to import typedef statements with template instantiation as its underlying type.
```c++
template<class T>
struct MagicWrapper {
T t;
};
struct MagicNumber {};
typedef MagicWrapper<MagicNumber> WrappedMagicNumber;
```
will be made available in Swift as if `WrappedMagicNumber` is a regular struct.
In C++, multiple distinct typedeffed instantiations resolve to the same canonical type. We implement this by creating a hidden intermediate struct that typedef aliasses.
The struct is named as `__CxxTemplateInst` plus Itanium mangled type of the instantiation. For the example above the name of the hidden struct is `__CxxTemplateInst12MagicWrapperI11MagicNumberE`. Double underscore (denoting a reserved C++ identifier) is used to discourage direct usage. We chose Itanium mangling scheme because it produces valid Swift identifiers and covers all C++ edge cases.
Imported module interface of the example above:
```swift
struct __CxxTemplateInst12MagicWrapperI11MagicNumberE {
var t: MagicNumber
}
struct MagicNumber {}
typealias WrappedMagicNumber = __CxxTemplateInst12MagicWrapperI11MagicNumberE
```
We modified the `SwiftLookupTable` logic to show hidden structs in `swift_ide_test` for convenience.
Co-authored-by: Rosica Dejanovska <rosica@google.com>
Co-authored-by: Dmitri Gribenko <gribozavr@gmail.com>
Co-authored-by: Robert Widmann <devteam.codafi@gmail.com>
In this PR we teach `ClangImporter` to import typedef statements with template instantiation as its underlying type.
```c++
template<class T>
struct MagicWrapper {
T t;
};
struct MagicNumber {};
typedef MagicWrapper<MagicNumber> WrappedMagicNumber;
```
will be made available in Swift as if `WrappedMagicNumber` is a regular struct.
In C++, multiple distinct typedeffed instantiations resolve to the same canonical type. We implement this by creating a hidden intermediate struct that typedef aliasses.
The struct is named as `__CxxTemplateInst` plus Itanium mangled type of the instantiation. For the example above the name of the hidden struct is `__CxxTemplateInst12MagicWrapperI11MagicNumberE`. Double underscore (denoting a reserved C++ identifier) is used to discourage direct usage. We chose Itanium mangling scheme because it produces valid Swift identifiers and covers all C++ edge cases.
Imported module interface of the example above:
```swift
struct __CxxTemplateInst12MagicWrapperI11MagicNumberE {
var t: MagicNumber
}
struct MagicNumber {}
typealias WrappedMagicNumber = __CxxTemplateInst12MagicWrapperI11MagicNumberE
```
We modified the `SwiftLookupTable` logic to show hidden structs in `swift_ide_test` for convenience.
Resolves https://bugs.swift.org/browse/SR-12591.
Co-authored-by: Rosica Dejanovska <rosica@google.com>
Co-authored-by: Dmitri Gribenko <gribozavr@gmail.com>
Co-authored-by: Robert Widmann <devteam.codafi@gmail.com>