Skip to content

Commit 6ba7a1e

Browse files
committed
[cxx-interop] Fix two issues with extending nested types across modules.
One fix allows extending nested records in other modules, the other fixes the same issue for namespaces.
1 parent bc15343 commit 6ba7a1e

12 files changed

+123
-7
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2527,6 +2527,10 @@ static bool isVisibleFromModule(const ClangModuleUnit *ModuleFilter,
25272527
auto *Importer = static_cast<ClangImporter *>(Ctx.getClangModuleLoader());
25282528
auto ClangNode = Importer->getEffectiveClangNode(VD);
25292529

2530+
// Decls in the __ObjC bridging header is always visible.
2531+
if (VD->getModuleContext() == Importer->getImportedHeaderModule())
2532+
return true;
2533+
25302534
// Macros can be "redeclared" by putting an equivalent definition in two
25312535
// different modules. (We don't actually check the equivalence.)
25322536
// FIXME: We're also not checking if the redeclaration is in /this/ module.

lib/ClangImporter/ImportDecl.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2467,6 +2467,11 @@ namespace {
24672467
for (auto redecl : decl->redecls())
24682468
Impl.ImportedDecls[{redecl, getVersion()}] = enumDecl;
24692469

2470+
// Because a namespaces's decl context is the bridging header, make sure
2471+
// we add them to the bridging header lookup table.
2472+
addEntryToLookupTable(*Impl.BridgingHeaderLookupTable,
2473+
const_cast<clang::NamespaceDecl *>(decl),
2474+
Impl.getNameImporter());
24702475
return enumDecl;
24712476
}
24722477

lib/ClangImporter/ImporterImpl.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -350,9 +350,6 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
350350
"<bridging-header-import>";
351351

352352
private:
353-
/// The Swift lookup table for the bridging header.
354-
std::unique_ptr<SwiftLookupTable> BridgingHeaderLookupTable;
355-
356353
/// The Swift lookup tables, per module.
357354
///
358355
/// Annoyingly, we list this table early so that it gets torn down after
@@ -416,6 +413,9 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
416413
llvm::SmallDenseMap<ModuleDecl *, SourceFile *> ClangSwiftAttrSourceFiles;
417414

418415
public:
416+
/// The Swift lookup table for the bridging header.
417+
std::unique_ptr<SwiftLookupTable> BridgingHeaderLookupTable;
418+
419419
/// Mapping of already-imported declarations.
420420
llvm::DenseMap<std::pair<const clang::Decl *, Version>, Decl *> ImportedDecls;
421421

test/IDE/complete_from_clang_framework.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ func testSwiftCompletions(foo: SwiftStruct) {
122122
// CLANG_BAR-DAG: Decl[GlobalVar]/OtherModule[Bar]: BAR_MACRO_1[#Int32#]{{; name=.+$}}
123123
// CLANG_BAR-DAG: Decl[Struct]/OtherModule[Bar]: SomeItemSet[#SomeItemSet#]
124124
// CLANG_BAR-DAG: Decl[TypeAlias]/OtherModule[Bar]: SomeEnvironment[#SomeItemSet#]
125+
// CLANG_BAR-DAG: Decl[TypeAlias]/OtherModule[__ObjC]: __NSConstantString[#__NSConstantString_tag#]; name=__NSConstantString
126+
// CLANG_BAR-DAG: Decl[TypeAlias]/OtherModule[__ObjC]: __builtin_ms_va_list[#UnsafeMutablePointer<CChar>#]; name=__builtin_ms_va_list
127+
// CLANG_BAR-DAG: Decl[TypeAlias]/OtherModule[__ObjC]: __builtin_va_list[#(__va_list_tag)#]; name=__builtin_va_list
125128
// CLANG_BAR: End completions
126129

127130
// CLANG_BOTH_FOO_BAR: Begin completions
@@ -148,12 +151,15 @@ func testCompleteModuleQualifiedFoo2() {
148151
Foo#^CLANG_QUAL_FOO_2^#
149152
// If the number of results below changes, then you need to add a result to the
150153
// list below.
151-
// CLANG_QUAL_FOO_2: Begin completions, 76 items
154+
// CLANG_QUAL_FOO_2: Begin completions, 82 items
152155
// CLANG_QUAL_FOO_2-DAG: Decl[Class]/OtherModule[Foo]: .FooClassBase[#FooClassBase#]{{; name=.+$}}
153156
// CLANG_QUAL_FOO_2-DAG: Decl[Class]/OtherModule[Foo]: .FooClassDerived[#FooClassDerived#]{{; name=.+$}}
154157
// CLANG_QUAL_FOO_2-DAG: Decl[Class]/OtherModule[Foo]: .ClassWithInternalProt[#ClassWithInternalProt#]{{; name=.+$}}
155158
// CLANG_QUAL_FOO_2-DAG: Decl[Struct]/OtherModule[Foo]: ._InternalStruct[#_InternalStruct#]
156159
// CLANG_QUAL_FOO_2-DAG: Decl[Class]/OtherModule[Foo]: .FooClassPropertyOwnership[#FooClassPropertyOwnership#]{{; name=.+$}}
160+
// CLANG_QUAL_FOO_2-DAG: Decl[TypeAlias]/OtherModule[__ObjC]: .__NSConstantString[#__NSConstantString_tag#]; name=__NSConstantString
161+
// CLANG_QUAL_FOO_2-DAG: Decl[TypeAlias]/OtherModule[__ObjC]: .__builtin_ms_va_list[#UnsafeMutablePointer<CChar>#]; name=__builtin_ms_va_list
162+
// CLANG_QUAL_FOO_2-DAG: Decl[TypeAlias]/OtherModule[__ObjC]: .__builtin_va_list[#(__va_list_tag)#]; name=__builtin_va_list
157163
// CLANG_QUAL_FOO_2-DAG: Decl[FreeFunction]/OtherModule[Foo]: ._internalTopLevelFunc()[#Void#]
158164
// CLANG_QUAL_FOO_2-DAG: Decl[Enum]/OtherModule[Foo]: .FooComparisonResult[#FooComparisonResult#]{{; name=.+$}}
159165
// CLANG_QUAL_FOO_2-DAG: Decl[FreeFunction]/OtherModule[Foo]: .fooFunc1({#(a): Int32#})[#Int32#]{{; name=.+$}}
@@ -217,14 +223,17 @@ func testCompleteModuleQualifiedFoo2() {
217223
// CLANG_QUAL_FOO_2-DAG: Decl[Class]/OtherModule[Foo]: .FooRepeatedMembers[#FooRepeatedMembers#]{{; name=.+$}}
218224
// CLANG_QUAL_FOO_2-DAG: Decl[Class]/OtherModule[Foo]: .FooClassWithClassProperties[#FooClassWithClassProperties#];
219225
// CLANG_QUAL_FOO_2-DAG: Decl[Enum]/OtherModule[Foo]: .SCNFilterMode[#SCNFilterMode#];
226+
// CLANG_QUAL_FOO_2-DAG: Decl[TypeAlias]/OtherModule[__ObjC]: .__NSConstantString[#__NSConstantString_tag#]; name=__NSConstantString
227+
// CLANG_QUAL_FOO_2-DAG: Decl[TypeAlias]/OtherModule[__ObjC]: .__builtin_ms_va_list[#UnsafeMutablePointer<CChar>#]; name=__builtin_ms_va_list
228+
// CLANG_QUAL_FOO_2-DAG: Decl[TypeAlias]/OtherModule[__ObjC]: .__builtin_va_list[#(__va_list_tag)#]; name=__builtin_va_list
220229
// CLANG_QUAL_FOO_2: End completions
221230
}
222231

223232
func testCompleteModuleQualifiedBar1() {
224233
Bar.#^CLANG_QUAL_BAR_1^#
225234
// If the number of results below changes, this is an indication that you need
226235
// to add a result to the appropriate list. Do not just bump the number!
227-
// CLANG_QUAL_BAR_1: Begin completions, 8 items
236+
// CLANG_QUAL_BAR_1: Begin completions, 11 items
228237
}
229238

230239
func testCompleteFunctionCall1() {
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef TEST_INTEROP_CXX_MODULES_INPUTS_BRIDGE_HEADER_H
2+
#define TEST_INTEROP_CXX_MODULES_INPUTS_BRIDGE_HEADER_H
3+
4+
struct Parent {
5+
struct Child {};
6+
};
7+
8+
namespace Namespace {
9+
struct InNamespace {};
10+
}
11+
12+
#endif // TEST_INTEROP_CXX_MODULES_INPUTS_BRIDGE_HEADER_H
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Namespace {
2+
header "namespace.h"
3+
requires cplusplus
4+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import Namespace
2+
3+
extension Namespace.Parent {
4+
public static func test() -> Int { 42 }
5+
}
6+
7+
extension Namespace.Parent.Child {
8+
public static func test() -> Int { 52 }
9+
}
10+
11+
extension Namespace.NestedNamespace.NestedStruct {
12+
public func test() -> Int { 62 }
13+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#ifndef TEST_INTEROP_CXX_MODULES_INPUTS_NAMESPACE_H
2+
#define TEST_INTEROP_CXX_MODULES_INPUTS_NAMESPACE_H
3+
4+
namespace Namespace {
5+
6+
struct Parent {
7+
struct Child {};
8+
};
9+
10+
namespace NestedNamespace {
11+
12+
struct NestedStruct {};
13+
14+
} // namespace NestedNamespace
15+
16+
} // namespace Namespace
17+
18+
#endif // TEST_INTEROP_CXX_MODULES_INPUTS_NAMESPACE_H
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
extension Parent.Child {
2+
public static func test() -> Int { 42 }
3+
}
4+
5+
extension Namespace.InNamespace {
6+
public func test() -> Int { 52 }
7+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: cd %t
3+
// RUN: %target-build-swift -I %S/Inputs -Xfrontend -enable-cxx-interop %S/Inputs/namespace-extension-lib.swift -emit-module -emit-library -module-name NamespaceExtensionLib
4+
// RUN: %target-build-swift %s -I %S/Inputs -Xfrontend -enable-cxx-interop -o %t/run -I %t/ -L %t/ -lNamespaceExtensionLib
5+
// RUN: %target-codesign %t/run
6+
// RUN: %target-run %t/run
7+
//
8+
// REQUIRES: executable_test
9+
10+
import StdlibUnittest
11+
import Namespace
12+
import NamespaceExtensionLib
13+
14+
var NamespacesTestSuite = TestSuite("Extension in library on namespace")
15+
16+
NamespacesTestSuite.test("Call functions from extension") {
17+
expectEqual(Namespace.Parent.test(), 42)
18+
expectEqual(Namespace.Parent.Child.test(), 52)
19+
expectEqual(Namespace.NestedNamespace.NestedStruct().test(), 62)
20+
}
21+
22+
runAllTests()
23+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: cd %t
3+
// RUN: %target-build-swift -import-objc-header %S/Inputs/bridge-header.h -Xfrontend -enable-cxx-interop %S/Inputs/struct-from-bridge-extension-lib.swift -emit-module -emit-library -module-name BridgeExtensionLib
4+
// RUN: %target-build-swift %s -import-objc-header %S/Inputs/bridge-header.h -Xfrontend -enable-cxx-interop -o %t/run -I %t/ -L %t/ -lBridgeExtensionLib
5+
// RUN: %target-codesign %t/run
6+
// RUN: %target-run %t/run
7+
//
8+
// REQUIRES: executable_test
9+
10+
import StdlibUnittest
11+
import BridgeExtensionLib
12+
13+
var BridgeTestSuite = TestSuite("Extension in library on nested types in bridge header")
14+
15+
BridgeTestSuite.test("Call functions from extension") {
16+
expectEqual(Parent.Child.test(), 42)
17+
expectEqual(Namespace.InNamespace().test(), 52)
18+
}
19+
20+
runAllTests()
21+

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@
4747
// CHECK-NEXT: }
4848
// CHECK-NEXT: typealias ForwardDeclaredClassTemplateOutOfLineChar = TemplatesNS1.TemplatesNS2.__CxxTemplateInstN12TemplatesNS112TemplatesNS237ForwardDeclaredClassTemplateOutOfLineIcEE
4949
// CHECK-NEXT: enum TemplatesNS4 {
50-
// CHECK-NEXT: struct __CxxTemplateInstN12TemplatesNS417HasSpecializationIcEE {
50+
// CHECK-NEXT: struct __CxxTemplateInstN12TemplatesNS417HasSpecializationIiEE {
5151
// CHECK-NEXT: init()
5252
// CHECK-NEXT: }
53-
// CHECK-NEXT: struct __CxxTemplateInstN12TemplatesNS417HasSpecializationIiEE {
53+
// CHECK-NEXT: struct __CxxTemplateInstN12TemplatesNS417HasSpecializationIcEE {
5454
// CHECK-NEXT: init()
5555
// CHECK-NEXT: }
5656
// CHECK-NEXT: struct HasSpecialization<> {

0 commit comments

Comments
 (0)