Skip to content

Commit d732513

Browse files
authored
Merge pull request #75269 from swiftlang/gaborh/forward-declare-classes
[cxx-interop] Forward declare classes
2 parents 8b45e33 + e6c3cb3 commit d732513

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)