Skip to content

Commit 8ae4ea1

Browse files
authored
Merge pull request #59149 from WANGJIEKE/cxx-interop-inout-param
[cxx interop] Export inout params as C++ reference
2 parents 3d9c72c + fb92680 commit 8ae4ea1

File tree

4 files changed

+85
-2
lines changed

4 files changed

+85
-2
lines changed

lib/PrintAsClang/DeclAndTypePrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,10 @@ class DeclAndTypePrinter::Implementation
889889
if (params->size()) {
890890
size_t index = 1;
891891
interleaveComma(*params, os, [&](const ParamDecl *param) {
892+
if (param->isInOut()) {
893+
os << "&";
894+
}
895+
892896
if (param->hasName()) {
893897
ClangSyntaxPrinter(os).printIdentifier(param->getName().str());
894898
} else {

lib/PrintAsClang/PrintClangFunction.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,16 @@ void DeclAndTypeClangFunctionPrinter::printFunctionSignature(
102102
: OutputLanguageMode::Cxx;
103103
// FIXME: Might need a PrintMultiPartType here.
104104
auto print = [&, this](Type ty, Optional<OptionalTypeKind> optionalKind,
105-
StringRef name) {
105+
StringRef name, bool isInOutParam) {
106106
// FIXME: add support for noescape and PrintMultiPartType,
107107
// see DeclAndTypePrinter::print.
108108
CFunctionSignatureTypePrinter typePrinter(os, typeMapping, outputLang);
109109
typePrinter.visit(ty, optionalKind);
110110

111+
if (isInOutParam) {
112+
os << (outputLang == OutputLanguageMode::Cxx ? " &" : " *");
113+
}
114+
111115
if (!name.empty()) {
112116
os << ' ';
113117
ClangSyntaxPrinter(os).printIdentifier(name);
@@ -142,7 +146,7 @@ void DeclAndTypeClangFunctionPrinter::printFunctionSignature(
142146
llvm::raw_string_ostream os(paramName);
143147
os << "_" << paramIndex;
144148
}
145-
print(objTy, argKind, paramName);
149+
print(objTy, argKind, paramName, param->isInOut());
146150
++paramIndex;
147151
});
148152
} else if (kind == FunctionSignatureKind::CFunctionProto) {
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend %s -typecheck -module-name Functions -clang-header-expose-public-decls -emit-clang-header-path %t/functions.h
3+
// RUN: %FileCheck %s < %t/functions.h
4+
5+
// RUN: %check-interop-cxx-header-in-clang(%t/functions.h)
6+
7+
// CHECK: SWIFT_EXTERN void $s9Functions8inOutIntyySizF(ptrdiff_t * x) SWIFT_NOEXCEPT SWIFT_CALL; // inOutInt(_:)
8+
// CHECK: SWIFT_EXTERN void $s9Functions11inOutTwoIntyySiz_SiztF(ptrdiff_t * x, ptrdiff_t * y) SWIFT_NOEXCEPT SWIFT_CALL; // inOutTwoInt(_:_:)
9+
// CHECK: SWIFT_EXTERN void $s9Functions13inOutTwoParamyySbz_SdztF(bool * x, double * y) SWIFT_NOEXCEPT SWIFT_CALL; // inOutTwoParam(_:_:)
10+
11+
// CHECK: inline void inOutInt(swift::Int & x) noexcept {
12+
// CHECK-NEXT: return _impl::$s9Functions8inOutIntyySizF(&x);
13+
// CHECK-NEXT: }
14+
15+
// CHECK: inline void inOutTwoInt(swift::Int & x, swift::Int & y) noexcept {
16+
// CHECK-NEXT: return _impl::$s9Functions11inOutTwoIntyySiz_SiztF(&x, &y);
17+
// CHECK-NEXT: }
18+
19+
// CHECK: inline void inOutTwoParam(bool & x, double & y) noexcept {
20+
// CHECK-NEXT: return _impl::$s9Functions13inOutTwoParamyySbz_SdztF(&x, &y);
21+
// CHECK-NEXT: }
22+
23+
public func inOutInt(_ x: inout Int) { x = Int() }
24+
25+
public func inOutTwoInt(_ x: inout Int, _ y: inout Int) {
26+
x += y
27+
y -= 2 * x
28+
}
29+
30+
public func inOutTwoParam(_ x: inout Bool, _ y: inout Double) {
31+
y = 3.14
32+
x = !x
33+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-swift-frontend %S/swift-primitive-inout-functions-cxx-bridging.swift -typecheck -module-name Functions -clang-header-expose-public-decls -emit-clang-header-path %t/functions.h
4+
5+
// RUN: %target-interop-build-clangxx -c %s -I %t -o %t/swift-functions-execution.o
6+
// RUN: %target-interop-build-swift %S/swift-primitive-inout-functions-cxx-bridging.swift -o %t/swift-functions-execution -Xlinker %t/swift-functions-execution.o -module-name Functions -Xfrontend -entry-point-function-name -Xfrontend swiftMain
7+
8+
// RUN: %target-codesign %t/swift-functions-execution
9+
// RUN: %target-run %t/swift-functions-execution
10+
11+
// REQUIRES: executable_test
12+
13+
#include <cassert>
14+
#include "functions.h"
15+
16+
#define VERIFY_INOUT_VALUE(FUNC, TYPENAME, INITIAL_VALUE, EXPECT_VALUE) \
17+
do { \
18+
TYPENAME variable = INITIAL_VALUE; \
19+
FUNC(variable); \
20+
assert(variable == EXPECT_VALUE); \
21+
} while (false);
22+
23+
int main() {
24+
using namespace Functions;
25+
26+
VERIFY_INOUT_VALUE(inOutInt, swift::Int, swift::Int{1}, swift::Int{0});
27+
28+
{
29+
swift::Int x{1}, y{2};
30+
inOutTwoInt(x, y);
31+
assert(x == swift::Int{3});
32+
assert(y == swift::Int{-4});
33+
}
34+
35+
{
36+
bool x = false;
37+
double y = 6.28;
38+
inOutTwoParam(x, y);
39+
assert(x);
40+
assert(y == 3.14);
41+
}
42+
}

0 commit comments

Comments
 (0)