Skip to content

Commit cc47851

Browse files
authored
Merge pull request #71022 from apple/egorzhdan/std-function-type-name
[cxx-interop] Emit function types as Swift closures in templated params
2 parents 77f18ee + 74c444d commit cc47851

File tree

4 files changed

+63
-1
lines changed

4 files changed

+63
-1
lines changed

lib/ClangImporter/ClangClassTemplateNamePrinter.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ struct TemplateInstantiationNamePrinter
2828
ImportNameVersion version)
2929
: swiftCtx(swiftCtx), nameImporter(nameImporter), version(version) {}
3030

31+
std::string VisitType(const clang::Type *type) {
32+
// Print "_" as a fallback if we couldn't emit a more meaningful type name.
33+
return "_";
34+
}
35+
3136
std::string VisitBuiltinType(const clang::BuiltinType *type) {
3237
Type swiftType = nullptr;
3338
switch (type->getKind()) {
@@ -51,7 +56,7 @@ struct TemplateInstantiationNamePrinter
5156
}
5257

5358
if (swiftType) {
54-
if (swiftType->is<NominalType>()) {
59+
if (swiftType->is<NominalType>() || swiftType->isVoid()) {
5560
return swiftType->getStringAsComponent();
5661
}
5762
}
@@ -108,6 +113,22 @@ struct TemplateInstantiationNamePrinter
108113

109114
return buffer.str().str();
110115
}
116+
117+
std::string VisitFunctionProtoType(const clang::FunctionProtoType *type) {
118+
llvm::SmallString<128> storage;
119+
llvm::raw_svector_ostream buffer(storage);
120+
121+
buffer << "((";
122+
llvm::interleaveComma(type->getParamTypes(), buffer,
123+
[&](const clang::QualType &paramType) {
124+
buffer << Visit(paramType.getTypePtr());
125+
});
126+
buffer << ") -> ";
127+
buffer << Visit(type->getReturnType().getTypePtr());
128+
buffer << ")";
129+
130+
return buffer.str().str();
131+
}
111132
};
112133

113134
std::string swift::importer::printClassTemplateSpecializationName(
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#ifndef TEST_INTEROP_CXX_TEMPLATES_INPUTS_CLASS_TEMPLATE_WITH_FUNCTION_ARGUMENT_H
2+
#define TEST_INTEROP_CXX_TEMPLATES_INPUTS_CLASS_TEMPLATE_WITH_FUNCTION_ARGUMENT_H
3+
4+
template <typename Fn>
5+
class function_wrapper;
6+
7+
template <typename Ret, typename... Params>
8+
class function_wrapper<Ret(Params...)> {
9+
Ret (*fn)(Params... params) = nullptr;
10+
};
11+
12+
typedef function_wrapper<bool(bool)> FuncBoolToBool;
13+
typedef function_wrapper<bool()> FuncVoidToBool;
14+
typedef function_wrapper<void(bool)> FuncBoolToVoid;
15+
typedef function_wrapper<void()> FuncVoidToVoid;
16+
typedef function_wrapper<int(int)> FuncIntToInt;
17+
typedef function_wrapper<int(int, int)> FuncIntIntToInt;
18+
typedef function_wrapper<void(int, int)> FuncIntIntToVoid;
19+
typedef function_wrapper<void(int, int, bool)> FuncIntIntBoolToVoid;
20+
21+
#endif // TEST_INTEROP_CXX_TEMPLATES_INPUTS_CLASS_TEMPLATE_WITH_FUNCTION_ARGUMENT_H

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ module ClassTemplateWithPrimitiveArgument {
88
requires cplusplus
99
}
1010

11+
module ClassTemplateWithFunctionParameter {
12+
header "class-template-with-function-parameter.h"
13+
requires cplusplus
14+
}
15+
1116
module ClassTemplateWithOutOfLineMember {
1217
header "class-template-with-static-out-of-line-member.h"
1318
requires cplusplus
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %target-swift-ide-test -print-module -module-to-print=ClassTemplateWithFunctionParameter -I %S/Inputs -source-filename=x -enable-experimental-cxx-interop | %FileCheck %s
2+
// RUN: %target-swift-ide-test -print-module -module-to-print=ClassTemplateWithFunctionParameter -I %S/Inputs -source-filename=x -cxx-interoperability-mode=upcoming-swift | %FileCheck %s
3+
4+
// CHECK: @available(*, unavailable
5+
// CHECK: struct function_wrapper<Fn> {
6+
// CHECK: }
7+
8+
// CHECK: typealias FuncBoolToBool = function_wrapper<((CBool) -> CBool)>
9+
// CHECK: typealias FuncVoidToBool = function_wrapper<(() -> CBool)>
10+
// CHECK: typealias FuncBoolToVoid = function_wrapper<((CBool) -> Void)>
11+
// CHECK: typealias FuncVoidToVoid = function_wrapper<(() -> Void)>
12+
// CHECK: typealias FuncIntToInt = function_wrapper<((CInt) -> CInt)>
13+
// CHECK: typealias FuncIntIntToInt = function_wrapper<((CInt, CInt) -> CInt)>
14+
// CHECK: typealias FuncIntIntToVoid = function_wrapper<((CInt, CInt) -> Void)>
15+
// CHECK: typealias FuncIntIntBoolToVoid = function_wrapper<((CInt, CInt, CBool) -> Void)>

0 commit comments

Comments
 (0)