Skip to content

Commit b527bb5

Browse files
authored
Merge pull request swiftlang#34730 from zoecarver/cxx/fix/nested-structs
[cxx-interop] Support nested C++ record types.
2 parents ef5a790 + 222d2fe commit b527bb5

File tree

4 files changed

+113
-1
lines changed

4 files changed

+113
-1
lines changed

lib/AST/ASTMangler.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1824,7 +1824,13 @@ ASTMangler::getSpecialManglingContext(const ValueDecl *decl,
18241824
hasNameForLinkage = !clangDecl->getDeclName().isEmpty();
18251825
if (hasNameForLinkage) {
18261826
auto *clangDC = clangDecl->getDeclContext();
1827-
if (isa<clang::NamespaceDecl>(clangDC)) return None;
1827+
// In C, "nested" structs, unions, enums, etc. will become sibilings:
1828+
// struct Foo { struct Bar { }; }; -> struct Foo { }; struct Bar { };
1829+
// Whereas in C++, nested records will actually be nested. So if this is
1830+
// a C++ record, simply treat it like a namespace and exit early.
1831+
if (isa<clang::NamespaceDecl>(clangDC) ||
1832+
isa<clang::CXXRecordDecl>(clangDC))
1833+
return None;
18281834
assert(clangDC->getRedeclContext()->isTranslationUnit() &&
18291835
"non-top-level Clang types not supported yet");
18301836
return ASTMangler::ObjCContext;

test/Interop/Cxx/class/Inputs/module.modulemap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,7 @@ module SynthesizedInitializers {
4141
module DebugInfo {
4242
header "debug-info.h"
4343
}
44+
45+
module NestedRecords {
46+
header "nested-records.h"
47+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
struct S1 {
2+
struct S2 {
3+
bool A : 1;
4+
};
5+
};
6+
7+
struct S3 {
8+
struct S4 { };
9+
};
10+
11+
union U1 {
12+
union U2 {};
13+
};
14+
15+
union U3 {
16+
enum E1 {};
17+
};
18+
19+
union U4 {
20+
struct S5 {};
21+
};
22+
23+
struct S6 {
24+
enum E3 {};
25+
};
26+
27+
struct S7 {
28+
union U5 {
29+
union U6 {};
30+
};
31+
};
32+
33+
struct S8 {
34+
struct S9 {
35+
union U7 {};
36+
};
37+
};
38+
39+
struct S10 {
40+
union U8 {
41+
enum E4 {};
42+
};
43+
};
44+
45+
// TODO: Nested class templates (SR-13853).
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// RUN: %target-swift-ide-test -print-module -module-to-print=NestedRecords -I %S/Inputs -source-filename=x -enable-cxx-interop | %FileCheck %s
2+
3+
// CHECK: struct S1 {
4+
// CHECK: struct S2 {
5+
// CHECK: var A: Bool
6+
// CHECK: }
7+
// CHECK: }
8+
9+
// CHECK: struct S3 {
10+
// CHECK: struct S4 {
11+
// CHECK: }
12+
// CHECK: }
13+
14+
// CHECK: struct U1 {
15+
// CHECK: struct U2 {
16+
// CHECK: }
17+
// CHECK: }
18+
19+
// CHECK: struct U3 {
20+
// CHECK: struct E1 : Equatable, RawRepresentable {
21+
// CHECK: typealias RawValue = {{UInt32|Int32}}
22+
// CHECK: }
23+
// CHECK: }
24+
25+
// CHECK: struct U4 {
26+
// CHECK: struct S5 {
27+
// CHECK: }
28+
// CHECK: }
29+
30+
// CHECK: struct S6 {
31+
// CHECK: struct E3 : Equatable, RawRepresentable {
32+
// CHECK: typealias RawValue = {{UInt32|Int32}}
33+
// CHECK: }
34+
// CHECK: init()
35+
// CHECK: }
36+
37+
// CHECK: struct S7 {
38+
// CHECK: struct U5 {
39+
// CHECK: struct U6 {
40+
// CHECK: }
41+
// CHECK: }
42+
// CHECK: }
43+
44+
// CHECK: struct S8 {
45+
// CHECK: struct S9 {
46+
// CHECK: struct U7 {
47+
// CHECK: }
48+
// CHECK: }
49+
// CHECK: }
50+
51+
// CHECK: struct S10 {
52+
// CHECK: struct U8 {
53+
// CHECK: struct E4 : Equatable, RawRepresentable {
54+
// CHECK: typealias RawValue = {{UInt32|Int32}}
55+
// CHECK: }
56+
// CHECK: }
57+
// CHECK: }

0 commit comments

Comments
 (0)