Skip to content

Commit ff222ac

Browse files
Setting hardcode SWIFT_NOEXCEPT and noexcept flags only to
non-throwing functions. Activating swift-functions-errors tests Inserting macros and additional parameters in C and C++ functions following the pattern to lowering to LLVM IR.
1 parent d128d81 commit ff222ac

File tree

11 files changed

+153
-35
lines changed

11 files changed

+153
-35
lines changed

include/swift/IRGen/IRABIDetailsProvider.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,16 @@ class IRABIDetailsProvider {
4747
SizeType alignment;
4848
};
4949

50+
/// Information about any ABI additional parameters.
51+
struct ABIAdditionalParam {
52+
enum class ABIParameterRole { Self, Error };
53+
54+
ABIParameterRole role;
55+
TypeDecl *type;
56+
};
57+
58+
SmallVector<ABIAdditionalParam, 1> ABIAdditionalParams;
59+
5060
/// Returns the size and alignment for the given type, or \c None if the type
5161
/// is not a fixed layout type.
5262
llvm::Optional<SizeAndAlignment>
@@ -99,6 +109,10 @@ class IRABIDetailsProvider {
99109
/// their tag indices from the given EnumDecl
100110
llvm::MapVector<EnumElementDecl *, unsigned> getEnumTagMapping(EnumDecl *ED);
101111

112+
/// Returns the additional params if they exist after lowering the function.
113+
SmallVector<ABIAdditionalParam, 1>
114+
getFunctionABIAdditionalParams(AbstractFunctionDecl *fd);
115+
102116
private:
103117
std::unique_ptr<IRABIDetailsProviderImpl> impl;
104118
};

include/swift/SIL/SILFunction.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,9 @@ class SILFunction
472472
SILFunction *getDynamicallyReplacedFunction() const {
473473
return ReplacedFunction;
474474
}
475+
476+
static SILFunction *getFunction(SILDeclRef ref, SILModule &M);
477+
475478
void setDynamicallyReplacedFunction(SILFunction *f) {
476479
assert(ReplacedFunction == nullptr && "already set");
477480
assert(!hasObjCReplacement());

lib/IRGen/IRABIDetailsProvider.cpp

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "swift/IRGen/IRABIDetailsProvider.h"
14+
#include "Callee.h"
1415
#include "FixedTypeInfo.h"
1516
#include "GenEnum.h"
1617
#include "GenType.h"
@@ -21,7 +22,9 @@
2122
#include "swift/AST/ASTContext.h"
2223
#include "swift/AST/IRGenOptions.h"
2324
#include "swift/AST/Types.h"
25+
#include "swift/SIL/SILFunctionBuilder.h"
2426
#include "swift/SIL/SILModule.h"
27+
#include "swift/Subsystems.h"
2528
#include "clang/CodeGen/ModuleBuilder.h"
2629
#include "clang/CodeGen/SwiftCallingConv.h"
2730
#include "llvm/IR/DerivedTypes.h"
@@ -125,8 +128,8 @@ class IRABIDetailsProviderImpl {
125128

126129
llvm::MapVector<EnumElementDecl *, unsigned> getEnumTagMapping(EnumDecl *ED) {
127130
llvm::MapVector<EnumElementDecl *, unsigned> elements;
128-
auto &enumImplStrat = getEnumImplStrategy(
129-
IGM, ED->getDeclaredType()->getCanonicalType());
131+
auto &enumImplStrat =
132+
getEnumImplStrategy(IGM, ED->getDeclaredType()->getCanonicalType());
130133

131134
for (auto *element : ED->getAllElements()) {
132135
auto tagIdx = enumImplStrat.getTagIndex(element);
@@ -136,6 +139,30 @@ class IRABIDetailsProviderImpl {
136139
return elements;
137140
}
138141

142+
llvm::SmallVector<IRABIDetailsProvider::ABIAdditionalParam, 1>
143+
getFunctionABIAdditionalParams(AbstractFunctionDecl *afd) {
144+
llvm::SmallVector<IRABIDetailsProvider::ABIAdditionalParam, 1> params;
145+
146+
auto function = SILFunction::getFunction(SILDeclRef(afd), *silMod);
147+
148+
auto silFuncType = function->getLoweredFunctionType();
149+
auto funcPointerKind =
150+
FunctionPointerKind(FunctionPointerKind::BasicKind::Function);
151+
auto signature = Signature::getUncached(IGM, silFuncType, funcPointerKind);
152+
153+
for (auto attrSet : signature.getAttributes()) {
154+
if (attrSet.hasAttribute(llvm::Attribute::AttrKind::SwiftSelf))
155+
params.push_back(
156+
{IRABIDetailsProvider::ABIAdditionalParam::ABIParameterRole::Self,
157+
typeConverter.Context.getOpaquePointerDecl()});
158+
if (attrSet.hasAttribute(llvm::Attribute::AttrKind::SwiftError))
159+
params.push_back(
160+
{IRABIDetailsProvider::ABIAdditionalParam::ABIParameterRole::Error,
161+
typeConverter.Context.getOpaquePointerDecl()});
162+
}
163+
return params;
164+
}
165+
139166
private:
140167
Lowering::TypeConverter typeConverter;
141168
// Default silOptions are sufficient, as we don't need to generated SIL.
@@ -158,6 +185,12 @@ IRABIDetailsProvider::getTypeSizeAlignment(const NominalTypeDecl *TD) {
158185
return impl->getTypeSizeAlignment(TD);
159186
}
160187

188+
llvm::SmallVector<IRABIDetailsProvider::ABIAdditionalParam, 1>
189+
IRABIDetailsProvider::getFunctionABIAdditionalParams(
190+
AbstractFunctionDecl *afd) {
191+
return impl->getFunctionABIAdditionalParams(afd);
192+
}
193+
161194
bool IRABIDetailsProvider::shouldPassIndirectly(Type t) {
162195
return impl->shouldPassIndirectly(t);
163196
}

lib/PrintAsClang/DeclAndTypePrinter.cpp

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include "clang/AST/DeclObjC.h"
4444
#include "clang/Basic/CharInfo.h"
4545
#include "clang/Basic/SourceManager.h"
46+
#include "SwiftToClangInteropContext.h"
4647

4748
using namespace swift;
4849
using namespace swift::objc_translation;
@@ -937,6 +938,28 @@ class DeclAndTypePrinter::Implementation
937938
StringRef symbolName;
938939
};
939940

941+
// Converts the array of ABIAdditionalParam into an array of AdditionalParam
942+
void convertABIAdditionalParams(
943+
AbstractFunctionDecl *FD, Type resultTy,
944+
llvm::SmallVector<IRABIDetailsProvider::ABIAdditionalParam, 1> ABIparams,
945+
llvm::SmallVector<DeclAndTypeClangFunctionPrinter::AdditionalParam, 2>
946+
&params) {
947+
for (auto param : ABIparams) {
948+
if (param.role ==
949+
IRABIDetailsProvider::ABIAdditionalParam::ABIParameterRole::Self)
950+
params.push_back(
951+
{DeclAndTypeClangFunctionPrinter::AdditionalParam::Role::Self,
952+
resultTy->getASTContext().getOpaquePointerType(),
953+
/*isIndirect=*/
954+
isa<FuncDecl>(FD) ? cast<FuncDecl>(FD)->isMutating() : false});
955+
if (param.role ==
956+
IRABIDetailsProvider::ABIAdditionalParam::ABIParameterRole::Error)
957+
params.push_back(
958+
{DeclAndTypeClangFunctionPrinter::AdditionalParam::Role::Error,
959+
resultTy->getASTContext().getOpaquePointerType()});
960+
}
961+
}
962+
940963
// Print out the extern C Swift ABI function signature.
941964
FuncionSwiftABIInformation printSwiftABIFunctionSignatureAsCxxFunction(
942965
AbstractFunctionDecl *FD, Optional<FunctionType *> givenFuncType = None,
@@ -962,7 +985,9 @@ class DeclAndTypePrinter::Implementation
962985
DeclAndTypeClangFunctionPrinter funcPrinter(os, owningPrinter.prologueOS,
963986
owningPrinter.typeMapping,
964987
owningPrinter.interopContext);
965-
llvm::SmallVector<DeclAndTypeClangFunctionPrinter::AdditionalParam, 1>
988+
auto ABIparams = owningPrinter.interopContext.getIrABIDetails()
989+
.getFunctionABIAdditionalParams(FD);
990+
llvm::SmallVector<DeclAndTypeClangFunctionPrinter::AdditionalParam, 2>
966991
additionalParams;
967992
if (selfTypeDeclContext && !isa<ConstructorDecl>(FD)) {
968993
additionalParams.push_back(
@@ -971,14 +996,19 @@ class DeclAndTypePrinter::Implementation
971996
/*isIndirect=*/
972997
isa<FuncDecl>(FD) ? cast<FuncDecl>(FD)->isMutating() : false});
973998
}
999+
if (funcTy->isThrowing() && !ABIparams.empty())
1000+
convertABIAdditionalParams(FD, resultTy, ABIparams, additionalParams);
1001+
9741002
funcPrinter.printFunctionSignature(
9751003
FD, funcABI.getSymbolName(), resultTy,
9761004
DeclAndTypeClangFunctionPrinter::FunctionSignatureKind::CFunctionProto,
9771005
additionalParams);
9781006
// Swift functions can't throw exceptions, we can only
9791007
// throw them from C++ when emitting C++ inline thunks for the Swift
9801008
// functions.
981-
os << " SWIFT_NOEXCEPT";
1009+
// FIXME: Support throwing exceptions for Swift errors.
1010+
if (!funcTy->isThrowing())
1011+
os << " SWIFT_NOEXCEPT";
9821012
if (!funcABI.useCCallingConvention())
9831013
os << " SWIFT_CALL";
9841014
printAvailability(FD);
@@ -1013,16 +1043,25 @@ class DeclAndTypePrinter::Implementation
10131043
DeclAndTypeClangFunctionPrinter funcPrinter(os, owningPrinter.prologueOS,
10141044
owningPrinter.typeMapping,
10151045
owningPrinter.interopContext);
1046+
llvm::SmallVector<DeclAndTypeClangFunctionPrinter::AdditionalParam, 2>
1047+
additionalParams;
1048+
auto ABIparams = owningPrinter.interopContext.getIrABIDetails()
1049+
.getFunctionABIAdditionalParams(FD);
1050+
if (funcTy->isThrowing() && !ABIparams.empty())
1051+
convertABIAdditionalParams(FD, resultTy, ABIparams, additionalParams);
1052+
10161053
funcPrinter.printFunctionSignature(
10171054
FD, FD->getName().getBaseIdentifier().get(), resultTy,
10181055
DeclAndTypeClangFunctionPrinter::FunctionSignatureKind::CxxInlineThunk);
10191056
// FIXME: Support throwing exceptions for Swift errors.
1020-
os << " noexcept";
1057+
if (!funcTy->isThrowing())
1058+
os << " noexcept";
10211059
printFunctionClangAttributes(FD, funcTy);
10221060
printAvailability(FD);
10231061
os << " {\n";
10241062
funcPrinter.printCxxThunkBody(funcABI.getSymbolName(), resultTy,
1025-
FD->getParameters());
1063+
FD->getParameters(), additionalParams,
1064+
funcTy->isThrowing());
10261065
os << "}\n";
10271066
}
10281067

lib/PrintAsClang/PrintAsClang.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ static void writePrologue(raw_ostream &out, ASTContext &ctx,
320320
emitMacro("SWIFT_CALL", "__attribute__((swiftcall))");
321321
emitMacro("SWIFT_INDIRECT_RESULT", "__attribute__((swift_indirect_result))");
322322
emitMacro("SWIFT_CONTEXT", "__attribute__((swift_context))");
323+
emitMacro("SWIFT_ERROR_RESULT", "__attribute__((swift_error_result))");
323324
// SWIFT_NOEXCEPT applies 'noexcept' in C++ mode only.
324325
emitCxxConditional(
325326
out, [&] { emitMacro("SWIFT_NOEXCEPT", "noexcept"); },

lib/PrintAsClang/PrintClangFunction.cpp

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -284,17 +284,23 @@ void DeclAndTypeClangFunctionPrinter::printFunctionSignature(
284284
os << ", ";
285285
HasParams = true;
286286
interleaveComma(additionalParams, os, [&](const AdditionalParam &param) {
287-
assert(param.role == AdditionalParam::Role::Self);
288-
CFunctionSignatureTypePrinterModifierDelegate delegate;
289-
delegate.prefixIndirectParamValueTypeInC = [](raw_ostream &os) {
290-
os << "SWIFT_CONTEXT ";
291-
};
292-
if (param.isIndirect) {
293-
(*delegate.prefixIndirectParamValueTypeInC)(os);
294-
os << "void * _Nonnull _self";
295-
} else {
296-
print(param.type, OptionalTypeKind::OTK_None, "_self",
297-
/*isInOut*/ false, delegate);
287+
if (param.role == AdditionalParam::Role::Self) {
288+
CFunctionSignatureTypePrinterModifierDelegate delegate;
289+
delegate.prefixIndirectParamValueTypeInC = [](raw_ostream &os) {
290+
os << "SWIFT_CONTEXT ";
291+
};
292+
if (FD->hasThrows())
293+
os << "SWIFT_CONTEXT ";
294+
if (param.isIndirect) {
295+
(*delegate.prefixIndirectParamValueTypeInC)(os);
296+
os << "void * _Nonnull _self";
297+
} else {
298+
print(param.type, OptionalTypeKind::OTK_None, "_self",
299+
/*isInOut*/ false, delegate);
300+
}
301+
} else if (param.role == AdditionalParam::Role::Error) {
302+
os << "SWIFT_ERROR_RESULT ";
303+
os << "void ** _error";
298304
}
299305
});
300306
}
@@ -338,7 +344,11 @@ void DeclAndTypeClangFunctionPrinter::printCxxToCFunctionParameterUse(
338344

339345
void DeclAndTypeClangFunctionPrinter::printCxxThunkBody(
340346
StringRef swiftSymbolName, Type resultTy, const ParameterList *params,
341-
ArrayRef<AdditionalParam> additionalParams) {
347+
ArrayRef<AdditionalParam> additionalParams, bool hasThrows) {
348+
if (hasThrows) {
349+
os << " void* opaqueError = nullptr;\n";
350+
os << " void* self = nullptr;\n";
351+
}
342352
auto printCallToCFunc = [&](Optional<StringRef> additionalParam) {
343353
os << cxx_synthesis::getCxxImplNamespaceName() << "::" << swiftSymbolName
344354
<< '(';
@@ -371,10 +381,18 @@ void DeclAndTypeClangFunctionPrinter::printCxxThunkBody(
371381
if (hasParams)
372382
os << ", ";
373383
interleaveComma(additionalParams, os, [&](const AdditionalParam &param) {
374-
assert(param.role == AdditionalParam::Role::Self);
375-
printCxxToCFunctionParameterUse(param.type, "*this", /*isInOut=*/false,
376-
/*isIndirect=*/param.isIndirect,
377-
param.role);
384+
if (param.role == AdditionalParam::Role::Self && !hasThrows)
385+
printCxxToCFunctionParameterUse(param.type, "*this", /*isInOut=*/false,
386+
/*isIndirect=*/param.isIndirect,
387+
param.role);
388+
else if(param.role == AdditionalParam::Role::Self && hasThrows)
389+
printCxxToCFunctionParameterUse(param.type, "self", /*isInOut=*/false,
390+
/*isIndirect=*/param.isIndirect,
391+
param.role);
392+
else if(param.role == AdditionalParam::Role::Error && hasThrows)
393+
printCxxToCFunctionParameterUse(param.type, "&opaqueError", /*isInOut=*/false,
394+
/*isIndirect=*/param.isIndirect,
395+
param.role);
378396
});
379397
}
380398

@@ -447,7 +465,7 @@ void DeclAndTypeClangFunctionPrinter::printCxxMethod(
447465
/*isIndirect=*/isMutating,
448466
});
449467
printCxxThunkBody(swiftSymbolName, resultTy, FD->getParameters(),
450-
additionalParams);
468+
additionalParams, FD->hasThrows());
451469
os << " }\n";
452470
}
453471

lib/PrintAsClang/PrintClangFunction.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "swift/AST/Type.h"
1717
#include "swift/Basic/LLVM.h"
18+
#include "swift/IRGen/IRABIDetailsProvider.h"
1819
#include "llvm/ADT/ArrayRef.h"
1920
#include "llvm/ADT/Optional.h"
2021
#include "llvm/ADT/StringRef.h"
@@ -52,7 +53,7 @@ class DeclAndTypeClangFunctionPrinter {
5253

5354
/// Information about any additional parameters.
5455
struct AdditionalParam {
55-
enum class Role { Self };
56+
enum class Role { Self, Error };
5657

5758
Role role;
5859
Type type;
@@ -83,7 +84,8 @@ class DeclAndTypeClangFunctionPrinter {
8384
/// Swift function.
8485
void printCxxThunkBody(StringRef swiftSymbolName, Type resultTy,
8586
const ParameterList *params,
86-
ArrayRef<AdditionalParam> additionalParams = {});
87+
ArrayRef<AdditionalParam> additionalParams = {},
88+
bool hasThrows = false);
8789

8890
/// Print the Swift method as C++ method declaration/definition, including
8991
/// constructors.

lib/SIL/IR/SILFunction.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "swift/SIL/SILProfiler.h"
2222
#include "swift/SIL/CFG.h"
2323
#include "swift/SIL/PrettyStackTrace.h"
24+
#include "../../SILGen/SILGen.h"
2425
#include "swift/AST/Availability.h"
2526
#include "swift/AST/GenericEnvironment.h"
2627
#include "swift/AST/Module.h"
@@ -874,3 +875,8 @@ visitArgEffects(std::function<void(int, bool, ArgEffectKind)> c) const {
874875
idx++;
875876
}
876877
}
878+
879+
SILFunction *SILFunction::getFunction(SILDeclRef ref, SILModule &M) {
880+
swift::Lowering::SILGenModule SILGenModule(M, ref.getModuleContext());
881+
return SILGenModule.getFunction(ref, swift::NotForDefinition);
882+
}

test/Interop/SwiftToCxx/functions/swift-functions-errors-execution.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
// RUN: %target-run %t/swift-functions-errors-execution | %FileCheck %s
1010

1111
// REQUIRES: executable_test
12-
// XFAIL: *
1312

1413
#include <cassert>
1514
#include "functions.h"
@@ -24,4 +23,4 @@ int main() {
2423
}
2524

2625
// CHECK: passEmptyThrowFunction
27-
// CHECK-NEXT: passThrowFunction
26+
// CHECK-NEXT: passThrowFunction

test/Interop/SwiftToCxx/functions/swift-functions-errors.swift

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,22 @@
88

99
// CHECK-LABEL: namespace _impl {
1010

11-
// CHECK: SWIFT_EXTERN void $s9Functions18emptyThrowFunctionyyKF(void) SWIFT_CALL; // emptyThrowFunction()
12-
// CHECK: SWIFT_EXTERN void $s9Functions13throwFunctionyyKF(void) SWIFT_CALL; // throwFunction()
11+
// CHECK: SWIFT_EXTERN void $s9Functions18emptyThrowFunctionyyKF(SWIFT_CONTEXT void * _Nonnull _self, SWIFT_ERROR_RESULT void ** _error) SWIFT_CALL; // emptyThrowFunction()
12+
// CHECK: SWIFT_EXTERN void $s9Functions13throwFunctionyyKF(SWIFT_CONTEXT void * _Nonnull _self, SWIFT_ERROR_RESULT void ** _error) SWIFT_CALL; // throwFunction()
1313

1414
// CHECK: }
1515

16-
//XFAIL: *
17-
18-
enum NaiveErrors: Error {
16+
enum NaiveErrors : Error {
1917
case returnError
2018
case throwError
2119
}
2220

2321
public func emptyThrowFunction() throws { print("passEmptyThrowFunction") }
2422

2523
// CHECK: inline void emptyThrowFunction() {
26-
// CHECK: return _impl::$s9Functions18emptyThrowFunctionyyKF();
24+
// CHECK: void* opaqueError = nullptr;
25+
// CHECK: void* self = nullptr;
26+
// CHECK: return _impl::$s9Functions18emptyThrowFunctionyyKF(self, &opaqueError);
2727
// CHECK: }
2828

2929
public func throwFunction() throws {
@@ -32,5 +32,7 @@ public func throwFunction() throws {
3232
}
3333

3434
// CHECK: inline void throwFunction() {
35-
// CHECK: return _impl::$s9Functions13throwFunctionyyKF();
36-
// CHECK: }
35+
// CHECK: void* opaqueError = nullptr;
36+
// CHECK: void* self = nullptr;
37+
// CHECK: return _impl::$s9Functions13throwFunctionyyKF(self, &opaqueError);
38+
// CHECK: }

0 commit comments

Comments
 (0)