mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge remote-tracking branch 'origin/main' into rebranch
This commit is contained in:
@@ -1238,7 +1238,7 @@ void DeclAndTypeClangFunctionPrinter::printCxxThunkBody(
|
||||
// Create the condition and the statement to throw an exception.
|
||||
if (hasThrows) {
|
||||
os << " if (opaqueError != nullptr)\n";
|
||||
os << " throw (swift::Error(opaqueError));\n";
|
||||
os << " throw (Swift::Error(opaqueError));\n";
|
||||
}
|
||||
|
||||
// Return the function result value if it doesn't throw.
|
||||
|
||||
@@ -156,26 +156,6 @@ static void printTypeMetadataResponseType(SwiftToClangInteropContext &ctx,
|
||||
funcSig.parameterTypes[0]);
|
||||
}
|
||||
|
||||
void printCxxNaiveException(raw_ostream &os) {
|
||||
os << "/// Naive exception class that should be thrown\n";
|
||||
os << "class NaiveException : public swift::Error {\n";
|
||||
os << "public:\n";
|
||||
os << " inline NaiveException(const char * _Nonnull msg) noexcept : "
|
||||
<< "msg_(msg) { }\n";
|
||||
os << " inline NaiveException(NaiveException&& other) noexcept : "
|
||||
"msg_(other.msg_) { other.msg_ = nullptr; }\n";
|
||||
os << " inline ~NaiveException() noexcept { }\n";
|
||||
os << " void operator =(NaiveException&& other) noexcept { auto temp = msg_;"
|
||||
<< " msg_ = other.msg_; other.msg_ = temp; }\n";
|
||||
os << " void operator =(const NaiveException&) noexcept = delete;";
|
||||
os << "\n";
|
||||
os << " inline const char * _Nonnull getMessage() const noexcept { "
|
||||
<< "return(msg_); }\n";
|
||||
os << "private:\n";
|
||||
os << " const char * _Nonnull msg_;\n";
|
||||
os << "};\n";
|
||||
}
|
||||
|
||||
void printPrimitiveGenericTypeTraits(raw_ostream &os, ASTContext &astContext,
|
||||
PrimitiveTypeMapping &typeMapping,
|
||||
bool isCForwardDefinition) {
|
||||
@@ -239,7 +219,6 @@ void swift::printSwiftToClangCoreScaffold(SwiftToClangInteropContext &ctx,
|
||||
/*isCForwardDefinition=*/true);
|
||||
});
|
||||
os << "\n";
|
||||
printCxxNaiveException(os);
|
||||
});
|
||||
os << "\n";
|
||||
// C++ only supports inline variables from C++17.
|
||||
|
||||
@@ -195,95 +195,6 @@ template <class T> inline void *_Nonnull getOpaquePointer(T &value) {
|
||||
|
||||
} // namespace _impl
|
||||
|
||||
extern "C" void *_Nonnull swift_errorRetain(void *_Nonnull swiftError) noexcept;
|
||||
|
||||
extern "C" void swift_errorRelease(void *_Nonnull swiftError) noexcept;
|
||||
|
||||
extern "C" int $ss5ErrorMp; // external global %swift.protocol, align 4
|
||||
|
||||
extern "C"
|
||||
const void * _Nullable
|
||||
swift_getTypeByMangledNameInContext(
|
||||
const char *_Nullable typeNameStart,
|
||||
size_t typeNameLength,
|
||||
const void *_Nullable context,
|
||||
const void *_Nullable const *_Nullable genericArgs) SWIFT_CALL;
|
||||
|
||||
extern "C" bool swift_dynamicCast(void *_Nullable dest, void *_Nullable src,
|
||||
const void *_Nullable srcType,
|
||||
const void * _Nullable targetType,
|
||||
uint32_t flags);
|
||||
|
||||
struct SymbolicP {
|
||||
alignas(2) uint8_t _1;
|
||||
uint32_t _2;
|
||||
uint8_t _3[2];
|
||||
uint8_t _4;
|
||||
} __attribute__((packed));
|
||||
|
||||
inline const void *_Nullable getErrorMetadata() {
|
||||
static swift::SymbolicP errorSymbol;
|
||||
static int *_Nonnull got_ss5ErrorMp = &$ss5ErrorMp;
|
||||
errorSymbol._1 = 2;
|
||||
errorSymbol._2 = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(&got_ss5ErrorMp) - reinterpret_cast<uintptr_t>(&errorSymbol._2));
|
||||
errorSymbol._3[0] = '_';
|
||||
errorSymbol._3[1] = 'p';
|
||||
errorSymbol._4 = 0;
|
||||
static_assert(sizeof(errorSymbol) == 8, "");
|
||||
auto charErrorSymbol = reinterpret_cast<const char *>(&errorSymbol);
|
||||
|
||||
const void *ptr2 =
|
||||
swift::swift_getTypeByMangledNameInContext(charErrorSymbol,
|
||||
sizeof(errorSymbol) - 1,
|
||||
nullptr, nullptr);
|
||||
return ptr2;
|
||||
}
|
||||
|
||||
class Error {
|
||||
public:
|
||||
Error() {}
|
||||
Error(void* _Nonnull swiftError) { opaqueValue = swiftError; }
|
||||
~Error() {
|
||||
if (opaqueValue)
|
||||
swift_errorRelease(opaqueValue);
|
||||
}
|
||||
void* _Nonnull getPointerToOpaquePointer() { return opaqueValue; }
|
||||
Error(Error &&other) : opaqueValue(other.opaqueValue) {
|
||||
other.opaqueValue = nullptr;
|
||||
}
|
||||
Error(const Error &other) {
|
||||
if (other.opaqueValue)
|
||||
swift_errorRetain(other.opaqueValue);
|
||||
opaqueValue = other.opaqueValue;
|
||||
}
|
||||
|
||||
// FIXME: Return a Swift::Optional instead.
|
||||
template<class T>
|
||||
T as() {
|
||||
alignas(alignof(T)) char buffer[sizeof(T)];
|
||||
const void *em = getErrorMetadata();
|
||||
void *ep = getPointerToOpaquePointer();
|
||||
auto metadata = swift::TypeMetadataTrait<T>::getTypeMetadata();
|
||||
|
||||
// Dynamic cast will release the error, so we need to retain it.
|
||||
swift::swift_errorRetain(ep);
|
||||
bool dynamicCast =
|
||||
swift::swift_dynamicCast(buffer, &ep, em, metadata,
|
||||
/*take on success destroy on failure*/ 6);
|
||||
|
||||
if (dynamicCast) {
|
||||
return swift::_impl::implClassFor<T>::type::returnNewValue([&](char *dest) {
|
||||
swift::_impl::implClassFor<T>::type::initializeWithTake(dest, buffer);
|
||||
});
|
||||
}
|
||||
abort();
|
||||
// FIXME: return nil.
|
||||
}
|
||||
|
||||
private:
|
||||
void * _Nonnull opaqueValue = nullptr;
|
||||
};
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
} // namespace swift
|
||||
|
||||
@@ -91,4 +91,92 @@ SWIFT_INLINE_THUNK cxxOverlay::IterationEndSentinel end(const Array<T> &) {
|
||||
return {};
|
||||
}
|
||||
|
||||
extern "C" void *_Nonnull swift_errorRetain(void *_Nonnull swiftError) noexcept;
|
||||
|
||||
extern "C" void swift_errorRelease(void *_Nonnull swiftError) noexcept;
|
||||
|
||||
extern "C" int $ss5ErrorMp; // external global %swift.protocol, align 4
|
||||
|
||||
extern "C" const void *_Nullable swift_getTypeByMangledNameInContext(
|
||||
const char *_Nullable typeNameStart, size_t typeNameLength,
|
||||
const void *_Nullable context,
|
||||
const void *_Nullable const *_Nullable genericArgs) SWIFT_CALL;
|
||||
|
||||
extern "C" bool swift_dynamicCast(void *_Nullable dest, void *_Nullable src,
|
||||
const void *_Nullable srcType,
|
||||
const void *_Nullable targetType,
|
||||
uint32_t flags);
|
||||
|
||||
struct SymbolicP {
|
||||
alignas(2) uint8_t _1;
|
||||
uint32_t _2;
|
||||
uint8_t _3[2];
|
||||
uint8_t _4;
|
||||
} __attribute__((packed));
|
||||
|
||||
inline const void *_Nullable getErrorMetadata() {
|
||||
static SymbolicP errorSymbol;
|
||||
static int *_Nonnull got_ss5ErrorMp = &$ss5ErrorMp;
|
||||
errorSymbol._1 = 2;
|
||||
errorSymbol._2 =
|
||||
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(&got_ss5ErrorMp) -
|
||||
reinterpret_cast<uintptr_t>(&errorSymbol._2));
|
||||
errorSymbol._3[0] = '_';
|
||||
errorSymbol._3[1] = 'p';
|
||||
errorSymbol._4 = 0;
|
||||
static_assert(sizeof(errorSymbol) == 8, "");
|
||||
auto charErrorSymbol = reinterpret_cast<const char *>(&errorSymbol);
|
||||
|
||||
const void *ptr2 = swift_getTypeByMangledNameInContext(
|
||||
charErrorSymbol, sizeof(errorSymbol) - 1, nullptr, nullptr);
|
||||
return ptr2;
|
||||
}
|
||||
|
||||
class Error {
|
||||
public:
|
||||
Error() {}
|
||||
Error(void *_Nonnull swiftError) { opaqueValue = swiftError; }
|
||||
~Error() {
|
||||
if (opaqueValue)
|
||||
swift_errorRelease(opaqueValue);
|
||||
}
|
||||
void *_Nonnull getPointerToOpaquePointer() { return opaqueValue; }
|
||||
Error(Error &&other) : opaqueValue(other.opaqueValue) {
|
||||
other.opaqueValue = nullptr;
|
||||
}
|
||||
Error(const Error &other) {
|
||||
if (other.opaqueValue)
|
||||
swift_errorRetain(other.opaqueValue);
|
||||
opaqueValue = other.opaqueValue;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Swift::Optional<T> as() {
|
||||
alignas(alignof(T)) char buffer[sizeof(T)];
|
||||
const void *em = getErrorMetadata();
|
||||
void *ep = getPointerToOpaquePointer();
|
||||
auto metadata = swift::TypeMetadataTrait<T>::getTypeMetadata();
|
||||
|
||||
// Dynamic cast will release the error, so we need to retain it.
|
||||
swift_errorRetain(ep);
|
||||
bool dynamicCast =
|
||||
swift_dynamicCast(buffer, &ep, em, metadata,
|
||||
/*take on success destroy on failure*/ 6);
|
||||
|
||||
if (dynamicCast) {
|
||||
auto result = swift::_impl::implClassFor<T>::type::returnNewValue(
|
||||
[&](char *dest) {
|
||||
swift::_impl::implClassFor<T>::type::initializeWithTake(dest,
|
||||
buffer);
|
||||
});
|
||||
return Swift::Optional<T>::init(result);
|
||||
}
|
||||
|
||||
return Swift::Optional<T>::none();
|
||||
}
|
||||
|
||||
private:
|
||||
void *_Nonnull opaqueValue = nullptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -98,18 +98,6 @@
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: #endif
|
||||
// CHECK-EMPTY:
|
||||
// CHECK-NEXT: /// Naive exception class that should be thrown
|
||||
// CHECK-NEXT: class NaiveException : public swift::Error {
|
||||
// CHECK-NEXT: public:
|
||||
// CHECK-NEXT: inline NaiveException(const char * _Nonnull msg) noexcept : msg_(msg) { }
|
||||
// CHECK-NEXT: inline NaiveException(NaiveException&& other) noexcept : msg_(other.msg_) { other.msg_ = nullptr; }
|
||||
// CHECK-NEXT: inline ~NaiveException() noexcept { }
|
||||
// CHECK-NEXT: void operator =(NaiveException&& other) noexcept { auto temp = msg_; msg_ = other.msg_; other.msg_ = temp; }
|
||||
// CHECK-NEXT: void operator =(const NaiveException&) noexcept = delete;
|
||||
// CHECK-NEXT: inline const char * _Nonnull getMessage() const noexcept { return(msg_); }
|
||||
// CHECK-NEXT: private:
|
||||
// CHECK-NEXT: const char * _Nonnull msg_;
|
||||
// CHECK-NEXT: };
|
||||
// CHECK-EMPTY:
|
||||
// CHECK-NEXT: } // namespace _impl
|
||||
// CHECK-EMPTY:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
|
||||
// RUN: %target-swift-frontend %S/swift-functions-errors.swift -typecheck -module-name Functions -clang-header-expose-decls=has-expose-attr -emit-clang-header-path %t/functions.h
|
||||
// RUN: %target-swift-frontend %S/swift-functions-errors.swift -typecheck -module-name Functions -enable-experimental-cxx-interop -emit-clang-header-path %t/functions.h
|
||||
|
||||
// RUN: %target-interop-build-clangxx -c %s -I %t -o %t/swift-functions-errors-execution.o
|
||||
// RUN: %target-interop-build-swift %S/swift-functions-errors.swift -o %t/swift-functions-errors-execution -Xlinker %t/swift-functions-errors-execution.o -module-name Functions -Xfrontend -entry-point-function-name -Xfrontend swiftMain
|
||||
@@ -25,24 +25,27 @@ int main() {
|
||||
|
||||
try {
|
||||
Functions::emptyThrowFunction();
|
||||
} catch (swift::Error& e) {
|
||||
} catch (Swift::Error& e) {
|
||||
printf("Exception\n");
|
||||
}
|
||||
try {
|
||||
Functions::throwFunction();
|
||||
} catch (swift::Error& e) {
|
||||
auto errorVal = e.as<Functions::NaiveErrors>();
|
||||
} catch (Swift::Error& e) {
|
||||
auto errorOpt = e.as<Functions::NaiveErrors>();
|
||||
assert(errorOpt.isSome());
|
||||
|
||||
auto errorVal = errorOpt.get();
|
||||
assert(errorVal == Functions::NaiveErrors::throwError);
|
||||
errorVal.getMessage();
|
||||
}
|
||||
try {
|
||||
Functions::throwFunctionWithReturn();
|
||||
} catch (swift::Error& e) {
|
||||
} catch (Swift::Error& e) {
|
||||
printf("Exception\n");
|
||||
}
|
||||
try {
|
||||
Functions::testDestroyedError();
|
||||
} catch(const swift::Error &e) { }
|
||||
} catch(const Swift::Error &e) { }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-swift-frontend %s -typecheck -module-name Functions -clang-header-expose-decls=has-expose-attr -emit-clang-header-path %t/functions.h
|
||||
// RUN: %target-swift-frontend %s -typecheck -module-name Functions -enable-experimental-cxx-interop -emit-clang-header-path %t/functions.h
|
||||
// RUN: %FileCheck %s < %t/functions.h
|
||||
|
||||
// RUN: %check-interop-cxx-header-in-clang(%t/functions.h)
|
||||
// RUN: %check-interop-cxx-header-in-clang(%t/functions.h -Wno-shadow -Wno-unused-function)
|
||||
|
||||
// CHECK-LABEL: namespace Functions __attribute__((swift_private)) {
|
||||
|
||||
@@ -31,7 +31,7 @@ public func emptyThrowFunction() throws { print("passEmptyThrowFunction") }
|
||||
// CHECK: void* _ctx = nullptr;
|
||||
// CHECK: _impl::$s9Functions18emptyThrowFunctionyyKF(_ctx, &opaqueError);
|
||||
// CHECK: if (opaqueError != nullptr)
|
||||
// CHECK: throw (swift::Error(opaqueError))
|
||||
// CHECK: throw (Swift::Error(opaqueError))
|
||||
// CHECK: }
|
||||
|
||||
class TestDestroyed {
|
||||
@@ -53,7 +53,7 @@ public func testDestroyedError() throws { throw DestroyedError() }
|
||||
// CHECK: void* _ctx = nullptr;
|
||||
// CHECK: _impl::$s9Functions18testDestroyedErroryyKF(_ctx, &opaqueError);
|
||||
// CHECK: if (opaqueError != nullptr)
|
||||
// CHECK: throw (swift::Error(opaqueError))
|
||||
// CHECK: throw (Swift::Error(opaqueError))
|
||||
// CHECK: }
|
||||
|
||||
@_expose(Cxx)
|
||||
@@ -67,7 +67,7 @@ public func throwFunction() throws {
|
||||
// CHECK: void* _ctx = nullptr;
|
||||
// CHECK: _impl::$s9Functions13throwFunctionyyKF(_ctx, &opaqueError);
|
||||
// CHECK: if (opaqueError != nullptr)
|
||||
// CHECK: throw (swift::Error(opaqueError))
|
||||
// CHECK: throw (Swift::Error(opaqueError))
|
||||
// CHECK: }
|
||||
|
||||
@_expose(Cxx)
|
||||
@@ -82,6 +82,6 @@ public func throwFunctionWithReturn() throws -> Int {
|
||||
// CHECK: void* _ctx = nullptr;
|
||||
// CHECK: auto returnValue = _impl::$s9Functions23throwFunctionWithReturnSiyKF(_ctx, &opaqueError);
|
||||
// CHECK: if (opaqueError != nullptr)
|
||||
// CHECK: throw (swift::Error(opaqueError))
|
||||
// CHECK: throw (Swift::Error(opaqueError))
|
||||
// CHECK: return returnValue;
|
||||
// CHECK: }
|
||||
|
||||
Reference in New Issue
Block a user