Skip to content

Commit 5e1c8ea

Browse files
authored
Merge pull request swiftlang#36881 from egorzhdan/cxx-lookup-fix
C++ Interop: fix crash for Swift extensions of C++ classes declared in namespaces
2 parents 8736683 + 9adad32 commit 5e1c8ea

File tree

8 files changed

+98
-24
lines changed

8 files changed

+98
-24
lines changed

lib/AST/ASTMangler.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2303,9 +2303,9 @@ void ASTMangler::appendAnyGenericType(const GenericTypeDecl *decl) {
23032303
isa<clang::ObjCCompatibleAliasDecl>(namedDecl)) {
23042304
appendOperator("a");
23052305
} else if (isa<clang::NamespaceDecl>(namedDecl)) {
2306-
// Note: Namespaces are not really structs, but since namespaces are
2306+
// Note: Namespaces are not really enums, but since namespaces are
23072307
// imported as enums, be consistent.
2308-
appendOperator("V");
2308+
appendOperator("O");
23092309
} else {
23102310
llvm_unreachable("unknown imported Clang type");
23112311
}

lib/ClangImporter/ClangImporter.cpp

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2732,36 +2732,41 @@ void ClangImporter::lookupTypeDecl(
27322732
clang::DeclarationName clangName(
27332733
&Impl.Instance->getASTContext().Idents.get(rawName));
27342734

2735-
clang::Sema::LookupNameKind lookupKind;
2735+
SmallVector<clang::Sema::LookupNameKind, 1> lookupKinds;
27362736
switch (kind) {
27372737
case ClangTypeKind::Typedef:
2738-
lookupKind = clang::Sema::LookupOrdinaryName;
2738+
lookupKinds.push_back(clang::Sema::LookupOrdinaryName);
27392739
break;
27402740
case ClangTypeKind::Tag:
2741-
lookupKind = clang::Sema::LookupTagName;
2741+
lookupKinds.push_back(clang::Sema::LookupTagName);
2742+
lookupKinds.push_back(clang::Sema::LookupNamespaceName);
27422743
break;
27432744
case ClangTypeKind::ObjCProtocol:
2744-
lookupKind = clang::Sema::LookupObjCProtocolName;
2745+
lookupKinds.push_back(clang::Sema::LookupObjCProtocolName);
27452746
break;
27462747
}
27472748

27482749
// Perform name lookup into the global scope.
27492750
auto &sema = Impl.Instance->getSema();
2750-
clang::LookupResult lookupResult(sema, clangName, clang::SourceLocation(),
2751-
lookupKind);
27522751
bool foundViaClang = false;
2753-
if (!Impl.DisableSourceImport &&
2754-
sema.LookupName(lookupResult, /*Scope=*/nullptr)) {
2755-
for (auto clangDecl : lookupResult) {
2756-
if (!isa<clang::TypeDecl>(clangDecl) &&
2757-
!isa<clang::ObjCContainerDecl>(clangDecl) &&
2758-
!isa<clang::ObjCCompatibleAliasDecl>(clangDecl)) {
2759-
continue;
2760-
}
2761-
auto *imported = Impl.importDecl(clangDecl, Impl.CurrentVersion);
2762-
if (auto *importedType = dyn_cast_or_null<TypeDecl>(imported)) {
2763-
foundViaClang = true;
2764-
receiver(importedType);
2752+
2753+
for (auto lookupKind : lookupKinds) {
2754+
clang::LookupResult lookupResult(sema, clangName, clang::SourceLocation(),
2755+
lookupKind);
2756+
if (!Impl.DisableSourceImport &&
2757+
sema.LookupName(lookupResult, /*Scope=*/ sema.TUScope)) {
2758+
for (auto clangDecl : lookupResult) {
2759+
if (!isa<clang::TypeDecl>(clangDecl) &&
2760+
!isa<clang::NamespaceDecl>(clangDecl) &&
2761+
!isa<clang::ObjCContainerDecl>(clangDecl) &&
2762+
!isa<clang::ObjCCompatibleAliasDecl>(clangDecl)) {
2763+
continue;
2764+
}
2765+
auto *imported = Impl.importDecl(clangDecl, Impl.CurrentVersion);
2766+
if (auto *importedType = dyn_cast_or_null<TypeDecl>(imported)) {
2767+
foundViaClang = true;
2768+
receiver(importedType);
2769+
}
27652770
}
27662771
}
27672772
}

test/ClangImporter/cxx_interop_ir.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@ func indirectUsage() {
99
useT(makeT())
1010
}
1111

12-
// CHECK-LABEL: define hidden swiftcc %swift.type* @"$s6cxx_ir14reflectionInfo3argypXpSo2nsV10CXXInteropE1TV_tF"
13-
// CHECK: %0 = call swiftcc %swift.metadata_response @"$sSo2nsV10CXXInteropE1TVMa"({{i64|i32}} 0)
12+
// CHECK-LABEL: define hidden swiftcc %swift.type* @"$s6cxx_ir14reflectionInfo3argypXpSo2nsO10CXXInteropE1TV_tF"
13+
// CHECK: %0 = call swiftcc %swift.metadata_response @"$sSo2nsO10CXXInteropE1TVMa"({{i64|i32}} 0)
1414
func reflectionInfo(arg: namespacedT) -> Any.Type {
1515
return type(of: arg)
1616
}
1717

18-
// CHECK: define hidden swiftcc void @"$s6cxx_ir24namespaceManglesIntoName3argySo2nsV10CXXInteropE1TV_tF"
18+
// CHECK: define hidden swiftcc void @"$s6cxx_ir24namespaceManglesIntoName3argySo2nsO10CXXInteropE1TV_tF"
1919
func namespaceManglesIntoName(arg: namespacedT) {
2020
}
2121

22-
// CHECK: define hidden swiftcc void @"$s6cxx_ir42namespaceManglesIntoNameForUsingShadowDecl3argySo2nsV10CXXInteropE14NamespacedTypeV_tF"
22+
// CHECK: define hidden swiftcc void @"$s6cxx_ir42namespaceManglesIntoNameForUsingShadowDecl3argySo2nsO10CXXInteropE14NamespacedTypeV_tF"
2323
func namespaceManglesIntoNameForUsingShadowDecl(arg: NamespacedType) {
2424
}
2525

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#ifndef TEST_INTEROP_CXX_CLASS_INPUTS_EXTENSIONS_H
2+
#define TEST_INTEROP_CXX_CLASS_INPUTS_EXTENSIONS_H
3+
4+
namespace Outer {
5+
namespace Space {
6+
7+
struct Foo {
8+
int a;
9+
};
10+
11+
}
12+
}
13+
14+
#endif //TEST_INTEROP_CXX_CLASS_INPUTS_EXTENSIONS_H

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ module Destructors {
2323
requires cplusplus
2424
}
2525

26+
module Extensions {
27+
header "extensions.h"
28+
requires cplusplus
29+
}
30+
2631
module LoadableTypes {
2732
header "loadable-types.h"
2833
requires cplusplus
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %target-run-simple-swift(-I %S/Inputs/ -Xfrontend -enable-cxx-interop)
2+
// REQUIRES: executable_test
3+
4+
import StdlibUnittest
5+
import Extensions
6+
7+
var CxxClassExtensionsTestSuite = TestSuite("CxxClassExtensions")
8+
9+
extension Outer.Space.Foo {
10+
func bar() -> Int32 { return a + 1 }
11+
}
12+
13+
CxxClassExtensionsTestSuite.test("calling extension method") {
14+
var foo = Outer.Space.Foo(a: 123)
15+
expectEqual(124, foo.bar())
16+
}
17+
18+
runAllTests()
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %target-swift-emit-ir %s -I %S/Inputs -enable-cxx-interop | %FileCheck %s
2+
//
3+
// We can't yet call member functions correctly on Windows (SR-13129).
4+
// XFAIL: OS=windows-msvc
5+
6+
import Extensions
7+
8+
extension Outer.Space.Foo {
9+
func foo() {}
10+
}
11+
12+
Outer.Space.Foo().foo()
13+
14+
// CHECK: call swiftcc void @"$sSo5OuterO5SpaceO10ExtensionsE3FooV4mainE3fooyyF"
15+
16+
// CHECK: define hidden swiftcc void @"$sSo5OuterO5SpaceO10ExtensionsE3FooV4mainE3fooyyF"
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %target-typecheck-verify-swift -I %S/Inputs -enable-cxx-interop
2+
3+
import Extensions
4+
5+
extension Outer.Space.Foo {
6+
func bar() -> Int32 { return a }
7+
}
8+
9+
extension Outer.Space.Foo: ExpressibleByIntegerLiteral {
10+
public init(integerLiteral value: IntegerLiteralType) {
11+
self.init(a: Int32(value))
12+
}
13+
}
14+
15+
var it: Outer.Space.Foo = 123
16+
let res = it.bar()

0 commit comments

Comments
 (0)