Skip to content

Commit 069e51d

Browse files
authored
Merge pull request #37443 from egorzhdan/cxx-namespace-alias
C++ Interop: import namespace aliases
2 parents 6a5f7fd + 51a8c47 commit 069e51d

File tree

5 files changed

+106
-2
lines changed

5 files changed

+106
-2
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2590,8 +2590,42 @@ namespace {
25902590
}
25912591

25922592
Decl *VisitNamespaceAliasDecl(const clang::NamespaceAliasDecl *decl) {
2593-
// FIXME: Implement once Swift has namespaces.
2594-
return nullptr;
2593+
Optional<ImportedName> correctSwiftName;
2594+
auto importedName = importFullName(decl, correctSwiftName);
2595+
auto name = importedName.getDeclName().getBaseIdentifier();
2596+
if (name.empty())
2597+
return nullptr;
2598+
2599+
if (correctSwiftName)
2600+
return importCompatibilityTypeAlias(decl, importedName,
2601+
*correctSwiftName);
2602+
2603+
auto dc =
2604+
Impl.importDeclContextOf(decl, importedName.getEffectiveContext());
2605+
if (!dc)
2606+
return nullptr;
2607+
2608+
auto aliasedDecl =
2609+
Impl.importDecl(decl->getAliasedNamespace(), getActiveSwiftVersion());
2610+
if (!aliasedDecl)
2611+
return nullptr;
2612+
2613+
Type aliasedType;
2614+
if (auto aliasedTypeDecl = dyn_cast<TypeDecl>(aliasedDecl))
2615+
aliasedType = aliasedTypeDecl->getDeclaredInterfaceType();
2616+
else if (auto aliasedExtDecl = dyn_cast<ExtensionDecl>(aliasedDecl))
2617+
// This happens if the alias points to its parent namespace.
2618+
aliasedType = aliasedExtDecl->getExtendedType();
2619+
else
2620+
return nullptr;
2621+
2622+
auto result = Impl.createDeclWithClangNode<TypeAliasDecl>(
2623+
decl, AccessLevel::Public, Impl.importSourceLoc(decl->getBeginLoc()),
2624+
SourceLoc(), name, Impl.importSourceLoc(decl->getLocation()),
2625+
/*GenericParams=*/nullptr, dc);
2626+
result->setUnderlyingType(aliasedType);
2627+
2628+
return result;
25952629
}
25962630

25972631
Decl *VisitLabelDecl(const clang::LabelDecl *decl) {

test/Interop/Cxx/namespace/Inputs/classes.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,35 @@ struct BasicStruct {
4040
};
4141
} // namespace ClassesNS3
4242

43+
namespace GlobalAliasToNS1 = ClassesNS1;
44+
45+
namespace ClassesNS4 {
46+
namespace AliasToGlobalNS1 = ::ClassesNS1;
47+
namespace AliasToGlobalNS2 = ::ClassesNS1::ClassesNS2;
48+
49+
namespace ClassesNS5 {
50+
struct BasicStruct {};
51+
} // namespace ClassesNS5
52+
53+
namespace AliasToInnerNS5 = ClassesNS5;
54+
namespace AliasToNS2 = ClassesNS1::ClassesNS2;
55+
56+
namespace AliasChainToNS1 = GlobalAliasToNS1;
57+
namespace AliasChainToNS2 = AliasChainToNS1::ClassesNS2;
58+
} // namespace ClassesNS4
59+
60+
namespace ClassesNS5 {
61+
struct BasicStruct {};
62+
namespace AliasToAnotherNS5 = ClassesNS4::ClassesNS5;
63+
64+
namespace ClassesNS5 {
65+
struct BasicStruct {};
66+
namespace AliasToNS5NS5 = ClassesNS5;
67+
} // namespace ClassesNS5
68+
69+
namespace AliasToGlobalNS5 = ::ClassesNS5;
70+
namespace AliasToLocalNS5 = ClassesNS5;
71+
namespace AliasToNS5 = ::ClassesNS5::ClassesNS5;
72+
} // namespace ClassesNS5
73+
4374
#endif // TEST_INTEROP_CXX_NAMESPACE_INPUTS_CLASSES_H

test/Interop/Cxx/namespace/classes-irgen.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Classes
66
// CHECK: call i8* @{{_ZN10ClassesNS111BasicStruct11basicMemberEv|"\?basicMember@BasicStruct@ClassesNS1@@QEAAPEBDXZ"}}(%"struct.ClassesNS1::BasicStruct"*
77
// CHECK: call i8* @{{_ZN10ClassesNS110ClassesNS211BasicStruct11basicMemberEv|"\?basicMember@BasicStruct@ClassesNS2@ClassesNS1@@QEAAPEBDXZ"}}(%"struct.ClassesNS1::ClassesNS2::BasicStruct"*
88
// CHECK: call i8* @{{_ZN10ClassesNS311BasicStruct11basicMemberEv|"\?basicMember@BasicStruct@ClassesNS3@@QEAAPEBDXZ"}}(%"struct.ClassesNS3::BasicStruct"*
9+
// CHECK: call i8* @{{_ZN10ClassesNS111BasicStruct11basicMemberEv|"\?basicMember@BasicStruct@ClassesNS1@@QEAAPEBDXZ"}}(%"struct.ClassesNS1::BasicStruct"*
910
// CHECK: ret void
1011
public func basicTests() {
1112
var basicStructInst = ClassesNS1.BasicStruct()
@@ -16,6 +17,9 @@ public func basicTests() {
1617

1718
var siblingBasicStruct = ClassesNS3.BasicStruct()
1819
siblingBasicStruct.basicMember()
20+
21+
var basicStructViaAlias = ClassesNS4.AliasToGlobalNS1.BasicStruct()
22+
basicStructViaAlias.basicMember()
1923
}
2024

2125
// CHECK-LABEL: define {{.*}}void @"$s4main15forwardDeclaredyyF"()

test/Interop/Cxx/namespace/classes-module-interface.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,34 @@
3232
// CHECK: }
3333
// CHECK: }
3434
// CHECK-NOT: extension
35+
36+
// CHECK: typealias GlobalAliasToNS1 = ClassesNS1
37+
// CHECK: extension ClassesNS4 {
38+
// CHECK: typealias AliasToGlobalNS1 = ClassesNS1
39+
// CHECK: typealias AliasToGlobalNS2 = ClassesNS1.ClassesNS2
40+
// CHECK: typealias AliasToInnerNS5 = ClassesNS4.ClassesNS5
41+
// CHECK: typealias AliasToNS2 = ClassesNS1.ClassesNS2
42+
// CHECK: typealias AliasChainToNS1 = ClassesNS1
43+
// CHECK: typealias AliasChainToNS2 = ClassesNS1.ClassesNS2
44+
// CHECK: }
45+
// CHECK: extension ClassesNS4.ClassesNS5 {
46+
// CHECK: struct BasicStruct {
47+
// CHECK: init()
48+
// CHECK: }
49+
// CHECK: }
50+
// CHECK: extension ClassesNS5 {
51+
// CHECK: struct BasicStruct {
52+
// CHECK: init()
53+
// CHECK: }
54+
// CHECK: typealias AliasToAnotherNS5 = ClassesNS4.ClassesNS5
55+
// CHECK: typealias AliasToGlobalNS5 = ClassesNS5
56+
// CHECK: typealias AliasToLocalNS5 = ClassesNS5.ClassesNS5
57+
// CHECK: typealias AliasToNS5 = ClassesNS5.ClassesNS5
58+
// CHECK: }
59+
// CHECK: extension ClassesNS5.ClassesNS5 {
60+
// CHECK: struct BasicStruct {
61+
// CHECK: init()
62+
// CHECK: }
63+
// CHECK: typealias AliasToNS5NS5 = ClassesNS5.ClassesNS5
64+
// CHECK: }
65+
// CHECK-NOT: extension

test/Interop/Cxx/namespace/classes.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ NamespacesTestSuite.test("Basic classes") {
2020
var siblingBasicStruct = ClassesNS3.BasicStruct()
2121
let siblingMemberCString = siblingBasicStruct.basicMember()
2222
expectEqual(String(cString: siblingMemberCString!), "ClassesNS3::BasicStruct::basicMember")
23+
24+
var basicStructViaAlias = ClassesNS4.AliasToGlobalNS1.BasicStruct()
25+
let basicMemberViaAliasCString = basicStructViaAlias.basicMember()
26+
expectEqual(String(cString: basicMemberViaAliasCString!), "ClassesNS1::BasicStruct::basicMember")
2327
}
2428

2529
NamespacesTestSuite.test("Forward declared classes") {

0 commit comments

Comments
 (0)