mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[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.
This commit is contained in:
@@ -2527,6 +2527,10 @@ static bool isVisibleFromModule(const ClangModuleUnit *ModuleFilter,
|
||||
auto *Importer = static_cast<ClangImporter *>(Ctx.getClangModuleLoader());
|
||||
auto ClangNode = Importer->getEffectiveClangNode(VD);
|
||||
|
||||
// Decls in the __ObjC bridging header is always visible.
|
||||
if (VD->getModuleContext() == Importer->getImportedHeaderModule())
|
||||
return true;
|
||||
|
||||
// Macros can be "redeclared" by putting an equivalent definition in two
|
||||
// different modules. (We don't actually check the equivalence.)
|
||||
// FIXME: We're also not checking if the redeclaration is in /this/ module.
|
||||
|
||||
@@ -2467,6 +2467,11 @@ namespace {
|
||||
for (auto redecl : decl->redecls())
|
||||
Impl.ImportedDecls[{redecl, getVersion()}] = enumDecl;
|
||||
|
||||
// Because a namespaces's decl context is the bridging header, make sure
|
||||
// we add them to the bridging header lookup table.
|
||||
addEntryToLookupTable(*Impl.BridgingHeaderLookupTable,
|
||||
const_cast<clang::NamespaceDecl *>(decl),
|
||||
Impl.getNameImporter());
|
||||
return enumDecl;
|
||||
}
|
||||
|
||||
|
||||
@@ -350,9 +350,6 @@ public:
|
||||
"<bridging-header-import>";
|
||||
|
||||
private:
|
||||
/// The Swift lookup table for the bridging header.
|
||||
std::unique_ptr<SwiftLookupTable> BridgingHeaderLookupTable;
|
||||
|
||||
/// The Swift lookup tables, per module.
|
||||
///
|
||||
/// Annoyingly, we list this table early so that it gets torn down after
|
||||
@@ -416,6 +413,9 @@ private:
|
||||
llvm::SmallDenseMap<ModuleDecl *, SourceFile *> ClangSwiftAttrSourceFiles;
|
||||
|
||||
public:
|
||||
/// The Swift lookup table for the bridging header.
|
||||
std::unique_ptr<SwiftLookupTable> BridgingHeaderLookupTable;
|
||||
|
||||
/// Mapping of already-imported declarations.
|
||||
llvm::DenseMap<std::pair<const clang::Decl *, Version>, Decl *> ImportedDecls;
|
||||
|
||||
|
||||
@@ -122,6 +122,9 @@ func testSwiftCompletions(foo: SwiftStruct) {
|
||||
// CLANG_BAR-DAG: Decl[GlobalVar]/OtherModule[Bar]: BAR_MACRO_1[#Int32#]{{; name=.+$}}
|
||||
// CLANG_BAR-DAG: Decl[Struct]/OtherModule[Bar]: SomeItemSet[#SomeItemSet#]
|
||||
// CLANG_BAR-DAG: Decl[TypeAlias]/OtherModule[Bar]: SomeEnvironment[#SomeItemSet#]
|
||||
// CLANG_BAR-DAG: Decl[TypeAlias]/OtherModule[__ObjC]: __NSConstantString[#__NSConstantString_tag#]; name=__NSConstantString
|
||||
// CLANG_BAR-DAG: Decl[TypeAlias]/OtherModule[__ObjC]: __builtin_ms_va_list[#UnsafeMutablePointer<CChar>#]; name=__builtin_ms_va_list
|
||||
// CLANG_BAR-DAG: Decl[TypeAlias]/OtherModule[__ObjC]: __builtin_va_list[#(__va_list_tag)#]; name=__builtin_va_list
|
||||
// CLANG_BAR: End completions
|
||||
|
||||
// CLANG_BOTH_FOO_BAR: Begin completions
|
||||
@@ -148,12 +151,15 @@ func testCompleteModuleQualifiedFoo2() {
|
||||
Foo#^CLANG_QUAL_FOO_2^#
|
||||
// If the number of results below changes, then you need to add a result to the
|
||||
// list below.
|
||||
// CLANG_QUAL_FOO_2: Begin completions, 76 items
|
||||
// CLANG_QUAL_FOO_2: Begin completions, 82 items
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[Class]/OtherModule[Foo]: .FooClassBase[#FooClassBase#]{{; name=.+$}}
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[Class]/OtherModule[Foo]: .FooClassDerived[#FooClassDerived#]{{; name=.+$}}
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[Class]/OtherModule[Foo]: .ClassWithInternalProt[#ClassWithInternalProt#]{{; name=.+$}}
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[Struct]/OtherModule[Foo]: ._InternalStruct[#_InternalStruct#]
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[Class]/OtherModule[Foo]: .FooClassPropertyOwnership[#FooClassPropertyOwnership#]{{; name=.+$}}
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[TypeAlias]/OtherModule[__ObjC]: .__NSConstantString[#__NSConstantString_tag#]; name=__NSConstantString
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[TypeAlias]/OtherModule[__ObjC]: .__builtin_ms_va_list[#UnsafeMutablePointer<CChar>#]; name=__builtin_ms_va_list
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[TypeAlias]/OtherModule[__ObjC]: .__builtin_va_list[#(__va_list_tag)#]; name=__builtin_va_list
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[FreeFunction]/OtherModule[Foo]: ._internalTopLevelFunc()[#Void#]
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[Enum]/OtherModule[Foo]: .FooComparisonResult[#FooComparisonResult#]{{; name=.+$}}
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[FreeFunction]/OtherModule[Foo]: .fooFunc1({#(a): Int32#})[#Int32#]{{; name=.+$}}
|
||||
@@ -217,6 +223,9 @@ func testCompleteModuleQualifiedFoo2() {
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[Class]/OtherModule[Foo]: .FooRepeatedMembers[#FooRepeatedMembers#]{{; name=.+$}}
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[Class]/OtherModule[Foo]: .FooClassWithClassProperties[#FooClassWithClassProperties#];
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[Enum]/OtherModule[Foo]: .SCNFilterMode[#SCNFilterMode#];
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[TypeAlias]/OtherModule[__ObjC]: .__NSConstantString[#__NSConstantString_tag#]; name=__NSConstantString
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[TypeAlias]/OtherModule[__ObjC]: .__builtin_ms_va_list[#UnsafeMutablePointer<CChar>#]; name=__builtin_ms_va_list
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[TypeAlias]/OtherModule[__ObjC]: .__builtin_va_list[#(__va_list_tag)#]; name=__builtin_va_list
|
||||
// CLANG_QUAL_FOO_2: End completions
|
||||
}
|
||||
|
||||
@@ -224,7 +233,7 @@ func testCompleteModuleQualifiedBar1() {
|
||||
Bar.#^CLANG_QUAL_BAR_1^#
|
||||
// If the number of results below changes, this is an indication that you need
|
||||
// to add a result to the appropriate list. Do not just bump the number!
|
||||
// CLANG_QUAL_BAR_1: Begin completions, 8 items
|
||||
// CLANG_QUAL_BAR_1: Begin completions, 11 items
|
||||
}
|
||||
|
||||
func testCompleteFunctionCall1() {
|
||||
|
||||
12
test/Interop/Cxx/modules/Inputs/bridge-header.h
Normal file
12
test/Interop/Cxx/modules/Inputs/bridge-header.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef TEST_INTEROP_CXX_MODULES_INPUTS_BRIDGE_HEADER_H
|
||||
#define TEST_INTEROP_CXX_MODULES_INPUTS_BRIDGE_HEADER_H
|
||||
|
||||
struct Parent {
|
||||
struct Child {};
|
||||
};
|
||||
|
||||
namespace Namespace {
|
||||
struct InNamespace {};
|
||||
}
|
||||
|
||||
#endif // TEST_INTEROP_CXX_MODULES_INPUTS_BRIDGE_HEADER_H
|
||||
4
test/Interop/Cxx/modules/Inputs/module.modulemap
Normal file
4
test/Interop/Cxx/modules/Inputs/module.modulemap
Normal file
@@ -0,0 +1,4 @@
|
||||
module Namespace {
|
||||
header "namespace.h"
|
||||
requires cplusplus
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import Namespace
|
||||
|
||||
extension Namespace.Parent {
|
||||
public static func test() -> Int { 42 }
|
||||
}
|
||||
|
||||
extension Namespace.Parent.Child {
|
||||
public static func test() -> Int { 52 }
|
||||
}
|
||||
|
||||
extension Namespace.NestedNamespace.NestedStruct {
|
||||
public func test() -> Int { 62 }
|
||||
}
|
||||
18
test/Interop/Cxx/modules/Inputs/namespace.h
Normal file
18
test/Interop/Cxx/modules/Inputs/namespace.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef TEST_INTEROP_CXX_MODULES_INPUTS_NAMESPACE_H
|
||||
#define TEST_INTEROP_CXX_MODULES_INPUTS_NAMESPACE_H
|
||||
|
||||
namespace Namespace {
|
||||
|
||||
struct Parent {
|
||||
struct Child {};
|
||||
};
|
||||
|
||||
namespace NestedNamespace {
|
||||
|
||||
struct NestedStruct {};
|
||||
|
||||
} // namespace NestedNamespace
|
||||
|
||||
} // namespace Namespace
|
||||
|
||||
#endif // TEST_INTEROP_CXX_MODULES_INPUTS_NAMESPACE_H
|
||||
@@ -0,0 +1,7 @@
|
||||
extension Parent.Child {
|
||||
public static func test() -> Int { 42 }
|
||||
}
|
||||
|
||||
extension Namespace.InNamespace {
|
||||
public func test() -> Int { 52 }
|
||||
}
|
||||
23
test/Interop/Cxx/modules/use-namespace-extension-lib.swift
Normal file
23
test/Interop/Cxx/modules/use-namespace-extension-lib.swift
Normal file
@@ -0,0 +1,23 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: cd %t
|
||||
// RUN: %target-build-swift -I %S/Inputs -Xfrontend -enable-cxx-interop %S/Inputs/namespace-extension-lib.swift -emit-module -emit-library -module-name NamespaceExtensionLib
|
||||
// RUN: %target-build-swift %s -I %S/Inputs -Xfrontend -enable-cxx-interop -o %t/run -I %t/ -L %t/ -lNamespaceExtensionLib
|
||||
// RUN: %target-codesign %t/run
|
||||
// RUN: %target-run %t/run
|
||||
//
|
||||
// REQUIRES: executable_test
|
||||
|
||||
import StdlibUnittest
|
||||
import Namespace
|
||||
import NamespaceExtensionLib
|
||||
|
||||
var NamespacesTestSuite = TestSuite("Extension in library on namespace")
|
||||
|
||||
NamespacesTestSuite.test("Call functions from extension") {
|
||||
expectEqual(Namespace.Parent.test(), 42)
|
||||
expectEqual(Namespace.Parent.Child.test(), 52)
|
||||
expectEqual(Namespace.NestedNamespace.NestedStruct().test(), 62)
|
||||
}
|
||||
|
||||
runAllTests()
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: cd %t
|
||||
// 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
|
||||
// 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
|
||||
// RUN: %target-codesign %t/run
|
||||
// RUN: %target-run %t/run
|
||||
//
|
||||
// REQUIRES: executable_test
|
||||
|
||||
import StdlibUnittest
|
||||
import BridgeExtensionLib
|
||||
|
||||
var BridgeTestSuite = TestSuite("Extension in library on nested types in bridge header")
|
||||
|
||||
BridgeTestSuite.test("Call functions from extension") {
|
||||
expectEqual(Parent.Child.test(), 42)
|
||||
expectEqual(Namespace.InNamespace().test(), 52)
|
||||
}
|
||||
|
||||
runAllTests()
|
||||
|
||||
@@ -47,10 +47,10 @@
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: typealias ForwardDeclaredClassTemplateOutOfLineChar = TemplatesNS1.TemplatesNS2.__CxxTemplateInstN12TemplatesNS112TemplatesNS237ForwardDeclaredClassTemplateOutOfLineIcEE
|
||||
// CHECK-NEXT: enum TemplatesNS4 {
|
||||
// CHECK-NEXT: struct __CxxTemplateInstN12TemplatesNS417HasSpecializationIcEE {
|
||||
// CHECK-NEXT: struct __CxxTemplateInstN12TemplatesNS417HasSpecializationIiEE {
|
||||
// CHECK-NEXT: init()
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: struct __CxxTemplateInstN12TemplatesNS417HasSpecializationIiEE {
|
||||
// CHECK-NEXT: struct __CxxTemplateInstN12TemplatesNS417HasSpecializationIcEE {
|
||||
// CHECK-NEXT: init()
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: struct HasSpecialization<> {
|
||||
|
||||
Reference in New Issue
Block a user