[interop][SwiftToCxx] Declare the generic usability type trait before the C++ class that represents the Swift type

This allows you to import a method that returns the type of the context in which the method is declared when such
type is a generic parameter in another type. This means that it's now possible to bridge the initializer for
RawRepresentable enums.
This commit is contained in:
Alex Lorenz
2022-09-15 16:13:35 -07:00
parent 2132cc91d0
commit 2a05109c58
15 changed files with 160 additions and 27 deletions

View File

@@ -274,17 +274,19 @@ public:
ClangValueTypePrinter::printClangTypeSwiftGenericTraits(os, typeDecl, &M);
}
void forwardDeclareCxxValueTypeIfNeeded(const NominalTypeDecl *NTD) {
forwardDeclare(NTD,
[&]() { ClangValueTypePrinter::forwardDeclType(os, NTD); });
}
void forwardDeclareType(const TypeDecl *TD) {
if (outputLangMode == OutputLanguageMode::Cxx) {
if (isa<StructDecl>(TD) || isa<EnumDecl>(TD)) {
auto *NTD = cast<NominalTypeDecl>(TD);
if (!addImport(NTD)) {
forwardDeclare(
NTD, [&]() { ClangValueTypePrinter::forwardDeclType(os, NTD); });
} else {
if (isa<StructDecl>(TD) && NTD->hasClangNode())
emitReferencedClangTypeMetadata(NTD);
}
if (!addImport(NTD))
forwardDeclareCxxValueTypeIfNeeded(NTD);
else if (isa<StructDecl>(TD) && NTD->hasClangNode())
emitReferencedClangTypeMetadata(NTD);
}
return;
}
@@ -471,6 +473,7 @@ public:
printer.getInteropContext().getExtensionsForNominalType(SD)) {
(void)forwardDeclareMemberTypes(ed->getMembers(), SD);
}
forwardDeclareCxxValueTypeIfNeeded(SD);
}
printer.print(SD);
return true;
@@ -536,6 +539,7 @@ public:
if (outputLangMode == OutputLanguageMode::Cxx) {
forwardDeclareMemberTypes(ED->getMembers(), ED);
forwardDeclareCxxValueTypeIfNeeded(ED);
}
if (seenTypes[ED].first == EmissionState::Defined)