[cxx-interop] Forward declare classes

The code already forward declared strutcs and enums. This patch extends
the logic to also forward declare classes. Unfortunately, there was some
fallout because some traits ended up defined multiple times for some
classes, so the code is now extended to only conditionally emit these
traits if no forward declaration was emitted for the type yet.

rdar://124022242
This commit is contained in:
Gabor Horvath
2024-07-16 17:21:18 +01:00
parent 01bd2b4f8c
commit e6c3cb3db1
5 changed files with 20 additions and 10 deletions

View File

@@ -117,11 +117,7 @@ public:
};
class ModuleWriter {
enum class EmissionState {
NotYetDefined = 0,
DefinitionRequested,
Defined
};
enum class EmissionState { NotYetDefined = 0, DefinitionRequested, Defined };
raw_ostream &os;
SmallPtrSetImpl<ImportModuleTy> &imports;
@@ -309,7 +305,7 @@ public:
void forwardDeclareType(const TypeDecl *TD) {
if (outputLangMode == OutputLanguageMode::Cxx) {
if (isa<StructDecl>(TD) || isa<EnumDecl>(TD)) {
if (isa<StructDecl>(TD) || isa<EnumDecl>(TD) || isa<ClassDecl>(TD)) {
auto *NTD = cast<NominalTypeDecl>(TD);
if (!addImport(NTD))
forwardDeclareCxxValueTypeIfNeeded(NTD);
@@ -474,7 +470,12 @@ public:
return false;
(void)forwardDeclareMemberTypes(CD->getMembers(), CD);
seenTypes[CD] = { EmissionState::Defined, true };
auto [it, inserted] =
seenTypes.try_emplace(CD, EmissionState::NotYetDefined, false);
if (outputLangMode == OutputLanguageMode::Cxx &&
(inserted || !it->second.second))
ClangValueTypePrinter::forwardDeclType(os, CD, printer);
it->second = {EmissionState::Defined, true};
os << '\n';
printer.print(CD);
return true;