mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Revert "Revert "[cxx-interop] Allow import-as-member for types in namespaces""
This reverts commit dd809c6452.
This commit is contained in:
@@ -220,7 +220,7 @@ bool SwiftLookupTable::contextRequiresName(ContextKind kind) {
|
||||
|
||||
/// Try to translate the given Clang declaration into a context.
|
||||
static std::optional<SwiftLookupTable::StoredContext>
|
||||
translateDeclToContext(clang::NamedDecl *decl) {
|
||||
translateDeclToContext(const clang::NamedDecl *decl) {
|
||||
// Tag declaration.
|
||||
if (auto tag = dyn_cast<clang::TagDecl>(decl)) {
|
||||
if (tag->getIdentifier())
|
||||
@@ -325,22 +325,46 @@ SwiftLookupTable::translateContext(EffectiveClangContext context) {
|
||||
|
||||
/// Lookup an unresolved context name and resolve it to a Clang
|
||||
/// declaration context or typedef name.
|
||||
clang::NamedDecl *SwiftLookupTable::resolveContext(StringRef unresolvedName) {
|
||||
const clang::NamedDecl *
|
||||
SwiftLookupTable::resolveContext(StringRef unresolvedName) {
|
||||
SmallVector<StringRef, 1> nameComponents;
|
||||
unresolvedName.split(nameComponents, '.');
|
||||
|
||||
EffectiveClangContext parentContext;
|
||||
|
||||
// Look for a context with the given Swift name.
|
||||
for (auto entry :
|
||||
lookup(SerializedSwiftName(unresolvedName),
|
||||
std::make_pair(ContextKind::TranslationUnit, StringRef()))) {
|
||||
if (auto decl = entry.dyn_cast<clang::NamedDecl *>()) {
|
||||
if (isa<clang::TagDecl>(decl) ||
|
||||
isa<clang::ObjCInterfaceDecl>(decl) ||
|
||||
isa<clang::TypedefNameDecl>(decl))
|
||||
return decl;
|
||||
for (auto nameComponent : nameComponents) {
|
||||
auto entries =
|
||||
parentContext
|
||||
? lookup(SerializedSwiftName(nameComponent), parentContext)
|
||||
: lookup(SerializedSwiftName(nameComponent),
|
||||
std::make_pair(ContextKind::TranslationUnit, StringRef()));
|
||||
bool entryFound = false;
|
||||
for (auto entry : entries) {
|
||||
if (auto decl = entry.dyn_cast<clang::NamedDecl *>()) {
|
||||
if (isa<clang::TagDecl>(decl) ||
|
||||
isa<clang::ObjCInterfaceDecl>(decl) ||
|
||||
isa<clang::NamespaceDecl>(decl)) {
|
||||
entryFound = true;
|
||||
parentContext = EffectiveClangContext(cast<clang::DeclContext>(decl));
|
||||
break;
|
||||
}
|
||||
if (auto typedefDecl = dyn_cast<clang::TypedefNameDecl>(decl)) {
|
||||
entryFound = true;
|
||||
parentContext = EffectiveClangContext(typedefDecl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we could not resolve this component of the qualified name, bail.
|
||||
if (!entryFound)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// FIXME: Search imported modules to resolve the context.
|
||||
|
||||
return nullptr;
|
||||
return parentContext.getAsDeclContext()
|
||||
? cast<clang::NamedDecl>(parentContext.getAsDeclContext())
|
||||
: parentContext.getTypedefName();
|
||||
}
|
||||
|
||||
void SwiftLookupTable::addCategory(clang::ObjCCategoryDecl *category) {
|
||||
|
||||
@@ -593,7 +593,7 @@ private:
|
||||
public:
|
||||
/// Lookup an unresolved context name and resolve it to a Clang
|
||||
/// named declaration.
|
||||
clang::NamedDecl *resolveContext(StringRef unresolvedName);
|
||||
const clang::NamedDecl *resolveContext(StringRef unresolvedName);
|
||||
|
||||
/// Lookup the set of entities with the given base name.
|
||||
///
|
||||
|
||||
@@ -13,4 +13,4 @@ Functions:
|
||||
- Name: ZXSpectrumSetMisnamedRegister
|
||||
SwiftName: 'setter:ZXSpectrum.misnamedRegister(self:newValue:)'
|
||||
- Name: ZXSpectrumHelperReset
|
||||
SwiftName: 'ZXSpectrum.Helper.reset()'
|
||||
SwiftName: 'ZXSpectrum::Helper.reset()'
|
||||
|
||||
32
test/Interop/Cxx/namespace/Inputs/import-as-member.h
Normal file
32
test/Interop/Cxx/namespace/Inputs/import-as-member.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#define SWIFT_NAME(name) __attribute__((swift_name(name)))
|
||||
|
||||
namespace MyNS {
|
||||
struct NestedStruct {
|
||||
int value = 123;
|
||||
};
|
||||
}
|
||||
|
||||
int nestedStruct_method(MyNS::NestedStruct p) SWIFT_NAME("MyNS.NestedStruct.method(self:)") { return p.value; }
|
||||
int nestedStruct_methodConstRef(const MyNS::NestedStruct &p) SWIFT_NAME("MyNS.NestedStruct.methodConstRef(self:)") { return p.value + 1; }
|
||||
inline int nestedStruct_methodInline(MyNS::NestedStruct p) SWIFT_NAME("MyNS.NestedStruct.methodInline(self:)") { return p.value + 2; }
|
||||
|
||||
namespace MyNS {
|
||||
namespace MyDeepNS {
|
||||
struct DeepNestedStruct {
|
||||
int value = 456;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
int deepNestedStruct_method(MyNS::MyDeepNS::DeepNestedStruct p) SWIFT_NAME("MyNS.MyDeepNS.DeepNestedStruct.method(self:)") { return p.value; }
|
||||
int deepNestedStruct_methodConstRef(const MyNS::MyDeepNS::DeepNestedStruct &p) SWIFT_NAME("MyNS.MyDeepNS.DeepNestedStruct.methodConstRef(self:)") { return p.value + 2; }
|
||||
|
||||
typedef MyNS::MyDeepNS::DeepNestedStruct DeepNestedStructTypedef;
|
||||
|
||||
int deepNestedStructTypedef_method(DeepNestedStructTypedef p) SWIFT_NAME("DeepNestedStructTypedef.methodTypedef(self:)") { return p.value + 3; }
|
||||
int deepNestedStructTypedef_methodQualName(MyNS::MyDeepNS::DeepNestedStruct p) SWIFT_NAME("DeepNestedStructTypedef.methodTypedefQualName(self:)") { return p.value + 4; }
|
||||
|
||||
namespace MyNS {
|
||||
int nestedStruct_nestedMethod(MyNS::NestedStruct p) SWIFT_NAME("MyNS.NestedStruct.nestedMethod(self:)") { return p.value + 3; }
|
||||
inline int nestedStruct_nestedMethodInline(MyNS::NestedStruct p) SWIFT_NAME("MyNS.NestedStruct.nestedMethodInline(self:)") { return p.value + 4; }
|
||||
}
|
||||
@@ -60,6 +60,12 @@ module Enums {
|
||||
requires cplusplus
|
||||
}
|
||||
|
||||
module ImportAsMember {
|
||||
header "import-as-member.h"
|
||||
export *
|
||||
requires cplusplus
|
||||
}
|
||||
|
||||
module MembersDirect {
|
||||
header "members-direct.h"
|
||||
requires cplusplus
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// RUN: %target-swift-ide-test -print-module -module-to-print=ImportAsMember -I %S/Inputs -source-filename=x -cxx-interoperability-mode=upcoming-swift | %FileCheck %s
|
||||
|
||||
// CHECK: extension MyNS.NestedStruct {
|
||||
// CHECK-NEXT: func method() -> Int32
|
||||
// CHECK-NEXT: func methodConstRef() -> Int32
|
||||
// CHECK-NEXT: func methodInline() -> Int32
|
||||
// CHECK-NEXT: func nestedMethod() -> Int32
|
||||
// CHECK-NEXT: func nestedMethodInline() -> Int32
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: extension MyNS.MyDeepNS.DeepNestedStruct {
|
||||
// CHECK-NEXT: func method() -> Int32
|
||||
// CHECK-NEXT: func methodConstRef() -> Int32
|
||||
// CHECK-NEXT: func methodTypedef() -> Int32
|
||||
// CHECK-NEXT: func methodTypedefQualName() -> Int32
|
||||
// CHECK-NEXT: }
|
||||
@@ -0,0 +1,24 @@
|
||||
// RUN: %target-typecheck-verify-swift -I %S/Inputs -cxx-interoperability-mode=upcoming-swift
|
||||
|
||||
import ImportAsMember
|
||||
|
||||
func takesNestedStruct(_ s: MyNS.NestedStruct) {
|
||||
_ = s.method()
|
||||
_ = s.methodConstRef()
|
||||
_ = s.nestedMethod()
|
||||
_ = s.nestedMethodInline()
|
||||
|
||||
_ = nestedStruct_method(s) // expected-error {{'nestedStruct_method' has been replaced by instance method 'MyNS.NestedStruct.method()'}}
|
||||
}
|
||||
|
||||
func takesDeepNestedStruct(_ s: MyNS.MyDeepNS.DeepNestedStruct) {
|
||||
_ = s.method()
|
||||
_ = s.methodConstRef()
|
||||
_ = s.methodTypedef()
|
||||
_ = s.methodTypedefQualName()
|
||||
|
||||
_ = deepNestedStruct_method(s) // expected-error {{'deepNestedStruct_method' has been replaced by instance method 'MyNS.MyDeepNS.DeepNestedStruct.method()'}}
|
||||
}
|
||||
|
||||
MyNS.method() // expected-error {{type 'MyNS' has no member 'method'}}
|
||||
MyNS.nestedMethod() // expected-error {{type 'MyNS' has no member 'nestedMethod'}}
|
||||
31
test/Interop/Cxx/namespace/import-as-member.swift
Normal file
31
test/Interop/Cxx/namespace/import-as-member.swift
Normal file
@@ -0,0 +1,31 @@
|
||||
// RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -cxx-interoperability-mode=upcoming-swift)
|
||||
|
||||
// REQUIRES: executable_test
|
||||
|
||||
import StdlibUnittest
|
||||
import ImportAsMember
|
||||
|
||||
var NamespacesTestSuite = TestSuite("Import as member of namespace")
|
||||
|
||||
NamespacesTestSuite.test("Struct in a namespace") {
|
||||
let s = MyNS.NestedStruct()
|
||||
expectEqual(123, s.method())
|
||||
expectEqual(124, s.methodConstRef())
|
||||
expectEqual(125, s.methodInline())
|
||||
}
|
||||
|
||||
NamespacesTestSuite.test("Struct in a deep namespace") {
|
||||
let s = MyNS.MyDeepNS.DeepNestedStruct()
|
||||
expectEqual(456, s.method())
|
||||
expectEqual(458, s.methodConstRef())
|
||||
expectEqual(459, s.methodTypedef())
|
||||
expectEqual(460, s.methodTypedefQualName())
|
||||
}
|
||||
|
||||
NamespacesTestSuite.test("Struct and function in a namespace") {
|
||||
let s = MyNS.NestedStruct()
|
||||
expectEqual(126, s.nestedMethod())
|
||||
expectEqual(127, s.nestedMethodInline())
|
||||
}
|
||||
|
||||
runAllTests()
|
||||
Reference in New Issue
Block a user