Skip to content

Commit 0e117ec

Browse files
authored
Merge pull request #79045 from swiftlang/gaborh/nested-classes
[cxx-interop] Support nested classes in reverse interop
2 parents 6f92302 + 8603dfe commit 0e117ec

File tree

7 files changed

+68
-14
lines changed

7 files changed

+68
-14
lines changed

include/swift/AST/SwiftNameTranslation.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ enum RepresentationError {
8484
UnrepresentableEnumCaseTuple,
8585
UnrepresentableProtocol,
8686
UnrepresentableMoveOnly,
87-
UnrepresentableNested,
8887
UnrepresentableMacro,
8988
UnrepresentableZeroSizedValueType,
9089
};

lib/AST/SwiftNameTranslation.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -249,11 +249,6 @@ swift::cxx_translation::getDeclRepresentation(
249249
return {Unsupported, UnrepresentableGeneric};
250250
genericSignature = typeDecl->getGenericSignature();
251251
}
252-
// Nested classes are not yet supported.
253-
if (isa<ClassDecl>(VD) && !typeDecl->hasClangNode() &&
254-
isa_and_nonnull<NominalTypeDecl>(
255-
typeDecl->getDeclContext()->getAsDecl()))
256-
return {Unsupported, UnrepresentableNested};
257252
if (!isa<ClassDecl>(typeDecl) && isZeroSized && (*isZeroSized)(typeDecl))
258253
return {Unsupported, UnrepresentableZeroSizedValueType};
259254
}
@@ -392,8 +387,6 @@ swift::cxx_translation::diagnoseRepresenationError(RepresentationError error,
392387
return Diagnostic(diag::expose_protocol_to_cxx_unsupported, vd);
393388
case UnrepresentableMoveOnly:
394389
return Diagnostic(diag::expose_move_only_to_cxx, vd);
395-
case UnrepresentableNested:
396-
return Diagnostic(diag::expose_nested_type_to_cxx, vd);
397390
case UnrepresentableMacro:
398391
return Diagnostic(diag::expose_macro_to_cxx, vd);
399392
case UnrepresentableZeroSizedValueType:

lib/PrintAsClang/DeclAndTypePrinter.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,6 @@ class DeclAndTypePrinter::Implementation
260260
auto VD = dyn_cast<ValueDecl>(member);
261261
if (!VD || !shouldInclude(VD))
262262
continue;
263-
// TODO: support nested classes.
264-
if (isa<ClassDecl>(member))
265-
continue;
266263
if (const auto *TD = dyn_cast<NominalTypeDecl>(member))
267264
printUsingForNestedType(TD, TD->getModuleContext());
268265
}

lib/PrintAsClang/PrintClangClassType.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,12 @@ void ClangClassTypePrinter::printClassTypeDecl(
116116
void ClangClassTypePrinter::printClassTypeReturnScaffold(
117117
raw_ostream &os, const ClassDecl *type, const ModuleDecl *moduleContext,
118118
llvm::function_ref<void(void)> bodyPrinter) {
119+
ClangSyntaxPrinter printer(type->getASTContext(), os);
119120
os << " return ";
120-
ClangSyntaxPrinter(type->getASTContext(), os).printModuleNamespaceQualifiersIfNeeded(
121-
type->getModuleContext(), moduleContext);
121+
printer.printModuleNamespaceQualifiersIfNeeded(type->getModuleContext(),
122+
moduleContext);
123+
if (!printer.printNestedTypeNamespaceQualifiers(type))
124+
os << "::";
122125
os << cxx_synthesis::getCxxImplNamespaceName() << "::";
123126
ClangValueTypePrinter::printCxxImplClassName(os, type);
124127
os << "::makeRetained(";

lib/PrintAsClang/PrintClangFunction.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,8 @@ class CFunctionSignatureTypePrinter
348348
if (typeUseKind == FunctionSignatureTypeUse::ParamType && !isInOutParam)
349349
os << "const ";
350350
printOptional(optionalKind, [&]() {
351-
ClangSyntaxPrinter(CT->getASTContext(), os).printBaseName(CT->getDecl());
351+
ClangSyntaxPrinter(CT->getASTContext(), os)
352+
.printPrimaryCxxTypeName(cd, moduleContext);
352353
});
353354
if (typeUseKind == FunctionSignatureTypeUse::ParamType)
354355
os << "&";
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-swift-frontend %S/nested-classes-in-cxx.swift -enable-library-evolution -typecheck -module-name Classes -clang-header-expose-decls=all-public -emit-clang-header-path %t/classes.h
4+
5+
// RUN: %target-interop-build-clangxx -std=c++17 -c %s -I %t -o %t/swift-classes-execution.o
6+
7+
// RUN: %target-interop-build-swift %S/nested-classes-in-cxx.swift -enable-library-evolution -o %t/swift-classes-execution -Xlinker %t/swift-classes-execution.o -module-name Classes -Xfrontend -entry-point-function-name -Xfrontend swiftMain
8+
9+
// RUN: %target-codesign %t/swift-classes-execution
10+
// RUN: %target-run %t/swift-classes-execution
11+
12+
// REQUIRES: executable_test
13+
14+
#include "classes.h"
15+
#include <cassert>
16+
17+
int main() {
18+
using namespace Classes;
19+
auto x = makeRecordConfig();
20+
RecordConfig::File::Gate y = x.getGate();
21+
assert(y.getProp() == 80);
22+
assert(y.computeValue() == 160);
23+
RecordConfig::AudioFormat z = x.getFile().getFormat();
24+
assert(z == RecordConfig::AudioFormat::ALAC);
25+
RecordConfig::File::Gate g = RecordConfig::File::Gate::init();
26+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend %s -enable-library-evolution -typecheck -module-name Classes -clang-header-expose-decls=all-public -emit-clang-header-path %t/classes.h
3+
4+
// RUN: %check-interop-cxx-header-in-clang(%t/classes.h -DSWIFT_CXX_INTEROP_HIDE_STL_OVERLAY -std=c++17)
5+
6+
public class RecordConfig {
7+
public enum AudioFormat {
8+
case PCM, ALAC, AAC
9+
}
10+
11+
public struct Directory {
12+
public var path: String?
13+
}
14+
15+
public class File {
16+
public var format: AudioFormat = .ALAC
17+
18+
public class Gate {
19+
public init() {}
20+
public var prop: Int32 = 80
21+
22+
public func computeValue() -> Int32 {
23+
return prop * 2
24+
}
25+
}
26+
}
27+
28+
public var directory = Directory()
29+
public var file = File()
30+
public var gate = File.Gate()
31+
}
32+
33+
public func makeRecordConfig() -> RecordConfig {
34+
return RecordConfig()
35+
}

0 commit comments

Comments
 (0)