Skip to content

Commit d254e83

Browse files
author
Gabor Horvath
committed
[cxx-interop] Fix not importing return type for certain functions
C++ namespaces are imported as enums. The importer triggered different code path for functions in C++ namespaces and functions in the global scope. As a result, we occasionally did not import the return type of certain C++ functions in namespace scope.
1 parent 8c8ed34 commit d254e83

File tree

3 files changed

+19
-2
lines changed

3 files changed

+19
-2
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3727,6 +3727,13 @@ namespace {
37273727
return nullptr;
37283728
}
37293729

3730+
static bool isClangNamespace(const DeclContext *dc) {
3731+
if (const auto *ed = dc->getSelfEnumDecl())
3732+
return isa<clang::NamespaceDecl>(ed->getClangDecl());
3733+
3734+
return false;
3735+
}
3736+
37303737
Decl *importFunctionDecl(
37313738
const clang::FunctionDecl *decl, ImportedName importedName,
37323739
std::optional<ImportedName> correctSwiftName,
@@ -3862,7 +3869,8 @@ namespace {
38623869

38633870
bool importFuncWithoutSignature =
38643871
isa<clang::CXXMethodDecl>(decl) && Impl.importSymbolicCXXDecls;
3865-
if (!dc->isModuleScopeContext() && !isa<clang::CXXMethodDecl>(decl)) {
3872+
if (!dc->isModuleScopeContext() && !isClangNamespace(dc) &&
3873+
!isa<clang::CXXMethodDecl>(decl)) {
38663874
// Handle initializers.
38673875
if (name.getBaseName().isConstructor()) {
38683876
assert(!accessorInfo);

test/Interop/Cxx/foreign-reference/Inputs/inheritance.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
// A wrapper around C++'s static_cast(), which allows Swift to get around interop's current lack of support for inheritance.
66
template <class I, class O> O cxxCast(I i) { return static_cast<O>(i); }
77

8+
namespace Foo {
9+
template <class I, class O>
10+
O cxxCast(I i) {
11+
return static_cast<O>(i);
12+
}
13+
} // namespace Foo
14+
815
// A minimal foreign reference type.
916
struct
1017
__attribute__((swift_attr("import_reference")))

test/Interop/Cxx/foreign-reference/inheritance.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ InheritanceTestSuite.test("Templated cast to base") {
2323
let sc: BaseT = cast(s)
2424
expectFalse(sc.isBase)
2525
let sx: BaseT = cxxCast(s) // should instantiate I to SubT and O to BaseT
26-
expectFalse(sc.isBase)
26+
expectFalse(sx.isBase)
27+
let sy: BaseT = Foo.cxxCast(s) // should instantiate I to SubT and O to BaseT
28+
expectFalse(sy.isBase)
2729
}
2830

2931
InheritanceTestSuite.test("Templated cast to itself") {

0 commit comments

Comments
 (0)