Swift was previously crashing while emitting an error ("could not generate C++ types from the generic Swift types provided") for C++ decls that do not have a name, such as constructors: `func->getName()` triggered an assertion.
Previously we tried to instantiate templates in unevaluated contexts. Some of these templates might not be instantiatable, which caused compile errors, while the equivalent C++ code compiles and runs with no issue.
This was problematic for `std::vector` with libstdc++ on Linux.
Fixes https://github.com/apple/swift/issues/61547.
Calling `clangSema.isCompleteType` tries to instantiate a template, and if that is impossible, returns `true`. This caused Swift to try to import invalid C++ template instantiations.
This was discovered during C++ interop adoption in SwiftCompilerSources:
Several LLVM headers declare a field with a type `DenseMap<int, ForwardDeclared>` where `ForwardDeclared` is defined in an implementation file (`.cpp`) and is not visible to ClangImporter. That is valid in C++ but caused an error when importing into Swift.
Due to a now default-enabled `undef` pass (llvm/llvm-project
1b1c8d83d3567a60280291c0adb95d1d60335509), a whole bunch of interop
IRGen tests are failing due to missing `undefs`, even though they don't
matter in these tests at all. Add regex matches so that these tests just
check for the name and types of the functions they care about.
If a templated C++ class is used from two different C++ modules, and those modules are included in Swift, Clang will create different two different redecls for the class & its methods.
For each of the methods, only one of the redecls would actually have a body, the other would have empty bodies. That prevents `ClangDeclFinder` from properly finding the symbols referenced from a method body, leading to a linker error in some cases, when the first redecl is missing a body.
This prevents `std::string` from being used on Linux:
```
/tmp/use-std-string-2dd593.o:use-std-string-2dd593.o:function void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag): error: undefined reference to 'bool __gnu_cxx::__is_null_pointer<char>(char*)'
/tmp/use-std-string-2dd593.o:use-std-string-2dd593.o:function void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag): error: undefined reference to 'std::iterator_traits<char*>::difference_type std::distance<char*>(char*, char*)'
clang-13: error: linker command failed with exit code 1 (use -v to see invocation)
<unknown>:0: error: link command failed with exit code 1 (use -v to see invocation)
```
Importing `type_traits` from libstdc++ currently causes a crash on Linux:
```
swift-ide-test: tools/clang/include/clang/AST/TypeNodes.inc:33: clang::TypeInfo clang::ASTContext::getTypeInfoImpl(const clang::Type *) const: Assertion `!T->isDependentType() && "should not see dependent types here"' failed.
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace.
Stack dump:
0. Program arguments: /home/egorzh/Builds/swift/swift/bin/swift-ide-test -print-module -module-to-print=std -source-filename=x -enable-cxx-interop
1. /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:1110:10: importing 'std::__do_is_implicitly_default_constructible_impl'
2. /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:1116:22: importing 'std::__do_is_implicitly_default_constructible_impl::__test'
```
This change fixes the crash by bailing on such functions.
The main point of this change is to make sure that a shared function always has a body: both, in the optimizer pipeline and in the swiftmodule file.
This is important because the compiler always needs to emit code for a shared function. Shared functions cannot be referenced from outside the module.
In several corner cases we missed to maintain this invariant which resulted in unresolved-symbol linker errors.
As side-effect of this change we can drop the shared_external SIL linkage and the IsSerializable flag, which simplifies the serialization and linkage concept.
Make sure each class template specialization has its own metadata/value witness table. The issue here is that we got the name wrong. We need to use the mangled name so its different for each specialization.
We used to incorrectly forward inout paramters in the thunk for both template paramters that aren't used in the signature and in the thunk for dependent types as Any.
Now this works in the simple case. We'll need to do something more complicated when we have an `inout Any` for dependent types because we will need to somehow cast without copying. This will probably require synthesising the SIL of the thunk manually.