Skip to content

Commit 4520c52

Browse files
committed
[interop][SwiftToCxx] handle indirect result values as part of parameter list
1 parent 1696f94 commit 4520c52

File tree

3 files changed

+40
-43
lines changed

3 files changed

+40
-43
lines changed

include/swift/IRGen/IRABIDetailsProvider.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,15 @@ class IRABIDetailsProvider {
123123
friend class LoweredFunctionSignature;
124124
};
125125

126-
class IndirectResultType {
126+
/// Represents a result value returned indirectly out of a function.
127+
class IndirectResultValue {
127128
public:
128129
/// Returns true if this indirect result type uses the `sret` LLVM
129130
/// attribute.
130131
inline bool hasSRet() const { return hasSRet_; }
131132

132133
private:
133-
inline IndirectResultType(bool hasSRet_) : hasSRet_(hasSRet_) {}
134+
inline IndirectResultValue(bool hasSRet_) : hasSRet_(hasSRet_) {}
134135
bool hasSRet_;
135136
friend class LoweredFunctionSignature;
136137
};
@@ -177,17 +178,16 @@ class IRABIDetailsProvider {
177178
llvm::Optional<DirectResultType> getDirectResultType() const;
178179

179180
/// Returns the number of indirect result values in this function signature.
180-
size_t getNumIndirectResults() const;
181-
182-
/// Returns lowered indirect result details.
183-
llvm::SmallVector<IndirectResultType, 1> getIndirectResultTypes() const;
181+
size_t getNumIndirectResultValues() const;
184182

185183
/// Traverse the entire parameter list of the function signature.
186184
///
187185
/// The parameter list can include actual Swift function parameters, result
188186
/// values returned indirectly, and additional values, like generic
189187
/// requirements for polymorphic calls and the error parameter as well.
190188
void visitParameterList(
189+
llvm::function_ref<void(const IndirectResultValue &)>
190+
indirectResultVisitor,
191191
llvm::function_ref<void(const DirectParameter &)> directParamVisitor,
192192
llvm::function_ref<void(const IndirectParameter &)>
193193
indirectParamVisitor);

lib/IRGen/IRABIDetailsProvider.cpp

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -301,23 +301,19 @@ IRABIDetailsProvider::LoweredFunctionSignature::getDirectResultType() const {
301301
}
302302

303303
size_t
304-
IRABIDetailsProvider::LoweredFunctionSignature::getNumIndirectResults() const {
304+
IRABIDetailsProvider::LoweredFunctionSignature::getNumIndirectResultValues()
305+
const {
305306
return abiDetails.indirectResults.size();
306307
}
307308

308-
llvm::SmallVector<
309-
IRABIDetailsProvider::LoweredFunctionSignature::IndirectResultType, 1>
310-
IRABIDetailsProvider::LoweredFunctionSignature::getIndirectResultTypes() const {
311-
llvm::SmallVector<IndirectResultType, 1> result;
312-
for (const auto &r : abiDetails.indirectResults)
313-
result.push_back(IndirectResultType(r.hasSRet));
314-
return result;
315-
}
316-
317309
void IRABIDetailsProvider::LoweredFunctionSignature::visitParameterList(
310+
llvm::function_ref<void(const IndirectResultValue &)> indirectResultVisitor,
318311
llvm::function_ref<void(const DirectParameter &)> directParamVisitor,
319312
llvm::function_ref<void(const IndirectParameter &)> indirectParamVisitor) {
320-
// FIXME: Traverse indirect result values.
313+
// Indirect result values come before parameters.
314+
llvm::SmallVector<IndirectResultValue, 1> result;
315+
for (const auto &r : abiDetails.indirectResults)
316+
indirectResultVisitor(IndirectResultValue(r.hasSRet));
321317

322318
// Traverse ABI parameters, mapping them back to the AST parameters.
323319
llvm::SmallVector<const ParamDecl *, 8> silParamMapping;

lib/PrintAsClang/PrintClangFunction.cpp

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -564,10 +564,10 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
564564

565565
auto directResultType = signature->getDirectResultType();
566566
// FIXME: support direct + indirect results.
567-
if (directResultType && signature->getNumIndirectResults() > 0)
567+
if (directResultType && signature->getNumIndirectResultValues() > 0)
568568
return ClangRepresentation::unsupported;
569569
// FIXME: support multiple indirect results.
570-
if (signature->getNumIndirectResults() > 1)
570+
if (signature->getNumIndirectResultValues() > 1)
571571
return ClangRepresentation::unsupported;
572572

573573
if (!directResultType) {
@@ -608,16 +608,6 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
608608
bool HasParams = false;
609609

610610
if (kind == FunctionSignatureKind::CFunctionProto) {
611-
// Indirect result is passed in as the first parameter.
612-
// FIXME: make visitor!
613-
for (const auto &result : signature->getIndirectResultTypes()) {
614-
HasParams = true;
615-
if (result.hasSRet())
616-
os << "SWIFT_INDIRECT_RESULT ";
617-
// FIXME: it would be nice to print out the C struct type here.
618-
os << "void * _Nonnull";
619-
}
620-
621611
// First, verify that the C++ param types are representable.
622612
for (auto param : *FD->getParameters()) {
623613
OptionalTypeKind optKind;
@@ -636,7 +626,7 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
636626
return resultingRepresentation;
637627
}
638628

639-
bool NeedsComma = HasParams;
629+
bool NeedsComma = false;
640630
auto emitNewParam = [&]() {
641631
HasParams = true;
642632
if (NeedsComma)
@@ -667,6 +657,14 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
667657
assert(!s.isUnsupported());
668658
};
669659
signature->visitParameterList(
660+
[&](const IRABIDetailsProvider::LoweredFunctionSignature::
661+
IndirectResultValue &indirectResult) {
662+
emitNewParam();
663+
if (indirectResult.hasSRet())
664+
os << "SWIFT_INDIRECT_RESULT ";
665+
// FIXME: it would be nice to print out the C struct type here.
666+
os << "void * _Nonnull";
667+
},
670668
[&](const IRABIDetailsProvider::LoweredFunctionSignature::
671669
DirectParameter &param) {
672670
emitNewParam();
@@ -744,7 +742,7 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
744742
->isAnyClassReferenceType()))
745743
os << "const ";
746744
os << "void * _Nonnull _self";
747-
} else if (param.role == AdditionalParam::Role::Error) {
745+
} else if (param.role == AdditionalParam::Role::Error) {
748746
os << "SWIFT_ERROR_RESULT ";
749747
os << "void * _Nullable * _Nullable _error";
750748
} else if (param.role == AdditionalParam::Role::GenericRequirement) {
@@ -840,21 +838,17 @@ void DeclAndTypeClangFunctionPrinter::printCxxThunkBody(
840838
os << cxx_synthesis::getCxxImplNamespaceName() << "::" << swiftSymbolName
841839
<< '(';
842840

843-
bool hasParams = false;
844-
if (additionalParam) {
845-
hasParams = true;
846-
os << *additionalParam;
847-
}
848-
849-
bool needsComma = hasParams;
841+
bool needsComma = false;
850842
size_t paramIndex = 1;
851-
auto printParamUse = [&](const ParamDecl &param, bool isIndirect,
852-
853-
std::string directTypeEncoding) {
843+
auto emitNewParam = [&]() {
854844
if (needsComma)
855845
os << ", ";
856846
needsComma = true;
857-
hasParams = true;
847+
};
848+
auto printParamUse = [&](const ParamDecl &param, bool isIndirect,
849+
850+
std::string directTypeEncoding) {
851+
emitNewParam();
858852
std::string paramName;
859853
if (param.isSelfParameter()) {
860854
paramName = "*this";
@@ -872,6 +866,13 @@ void DeclAndTypeClangFunctionPrinter::printCxxThunkBody(
872866
};
873867

874868
signature->visitParameterList(
869+
[&](const IRABIDetailsProvider::LoweredFunctionSignature::
870+
IndirectResultValue &) {
871+
emitNewParam();
872+
assert(additionalParam);
873+
os << *additionalParam;
874+
additionalParam = None;
875+
},
875876
[&](const IRABIDetailsProvider::LoweredFunctionSignature::
876877
DirectParameter &param) {
877878
printParamUse(
@@ -885,7 +886,7 @@ void DeclAndTypeClangFunctionPrinter::printCxxThunkBody(
885886
});
886887

887888
if (additionalParams.size()) {
888-
if (hasParams)
889+
if (needsComma)
889890
os << ", ";
890891
interleaveComma(additionalParams, os, [&](const AdditionalParam &param) {
891892
if (param.role == AdditionalParam::Role::GenericRequirement) {

0 commit comments

Comments
 (0)