Skip to content

Commit e6c3cb3

Browse files
author
Gabor Horvath
committed
[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
1 parent 01bd2b4 commit e6c3cb3

File tree

5 files changed

+20
-10
lines changed

5 files changed

+20
-10
lines changed

lib/PrintAsClang/DeclAndTypePrinter.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,8 +325,6 @@ class DeclAndTypePrinter::Implementation
325325

326326
if (outputLang == OutputLanguageMode::Cxx) {
327327
// FIXME: Non objc class.
328-
// FIXME: forward decl should be handled by ModuleWriter.
329-
ClangValueTypePrinter::forwardDeclType(os, CD, owningPrinter);
330328
ClangClassTypePrinter(os).printClassTypeDecl(
331329
CD, [&]() { printMembers(CD->getMembers()); }, owningPrinter);
332330
recordEmittedDeclInCurrentCxxLexicalScope(CD);

lib/PrintAsClang/DeclAndTypePrinter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "OutputLanguageMode.h"
1717

18+
#include "swift/AST/Decl.h"
1819
#include "swift/AST/Type.h"
1920
// for OptionalTypeKind
2021
#include "swift/ClangImporter/ClangImporter.h"

lib/PrintAsClang/ModuleContentsWriter.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,7 @@ class ReferencedTypeFinder : public TypeDeclFinder {
117117
};
118118

119119
class ModuleWriter {
120-
enum class EmissionState {
121-
NotYetDefined = 0,
122-
DefinitionRequested,
123-
Defined
124-
};
120+
enum class EmissionState { NotYetDefined = 0, DefinitionRequested, Defined };
125121

126122
raw_ostream &os;
127123
SmallPtrSetImpl<ImportModuleTy> &imports;
@@ -309,7 +305,7 @@ class ModuleWriter {
309305

310306
void forwardDeclareType(const TypeDecl *TD) {
311307
if (outputLangMode == OutputLanguageMode::Cxx) {
312-
if (isa<StructDecl>(TD) || isa<EnumDecl>(TD)) {
308+
if (isa<StructDecl>(TD) || isa<EnumDecl>(TD) || isa<ClassDecl>(TD)) {
313309
auto *NTD = cast<NominalTypeDecl>(TD);
314310
if (!addImport(NTD))
315311
forwardDeclareCxxValueTypeIfNeeded(NTD);
@@ -474,7 +470,12 @@ class ModuleWriter {
474470
return false;
475471

476472
(void)forwardDeclareMemberTypes(CD->getMembers(), CD);
477-
seenTypes[CD] = { EmissionState::Defined, true };
473+
auto [it, inserted] =
474+
seenTypes.try_emplace(CD, EmissionState::NotYetDefined, false);
475+
if (outputLangMode == OutputLanguageMode::Cxx &&
476+
(inserted || !it->second.second))
477+
ClangValueTypePrinter::forwardDeclType(os, CD, printer);
478+
it->second = {EmissionState::Defined, true};
478479
os << '\n';
479480
printer.print(CD);
480481
return true;

lib/PrintAsClang/PrintClangValueType.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ class ClangValueTypePrinter {
4141
/// corresponds to the given structure or enum declaration.
4242
void printValueTypeDecl(const NominalTypeDecl *typeDecl,
4343
llvm::function_ref<void(void)> bodyPrinter,
44-
4544
DeclAndTypePrinter &declAndTypePrinter);
4645

4746
/// Print the use of a C++ struct/enum parameter value as it's passed to the
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend %s -typecheck -module-name Class -clang-header-expose-decls=all-public -emit-clang-header-path %t/class.h
3+
4+
// RUN: %check-interop-cxx-header-in-clang(%t/class.h)
5+
6+
public class SwiftNode {
7+
}
8+
9+
public struct SwiftLinkedList {
10+
public var head: SwiftNode
11+
}

0 commit comments

Comments
 (0)