mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge pull request #61823 from Robertorosmaninho/interop/ExpectedClassForErrorHandling
[Interop][SwiftToCxx] Introduces swift::Expected
This commit is contained in:
@@ -799,6 +799,7 @@ EmittedClangHeaderDependencyInfo swift::printModuleContentsAsCxx(
|
||||
os << "#ifndef SWIFT_CXX_INTEROP_HIDE_STL_OVERLAY\n";
|
||||
os << "#include <string>\n";
|
||||
os << "#endif\n";
|
||||
os << "#include <new>\n";
|
||||
// Embed an overlay for the standard library.
|
||||
ClangSyntaxPrinter(moduleOS).printIncludeForShimHeader(
|
||||
"_SwiftStdlibCxxOverlay.h");
|
||||
|
||||
@@ -688,6 +688,8 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
|
||||
ClangRepresentation::representable;
|
||||
|
||||
// Print out the return type.
|
||||
if (FD->hasThrows() && outputLang == OutputLanguageMode::Cxx)
|
||||
os << "Swift::ThrowingResult<";
|
||||
if (kind == FunctionSignatureKind::CFunctionProto) {
|
||||
// First, verify that the C++ return type is representable.
|
||||
{
|
||||
@@ -740,7 +742,8 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
|
||||
.isUnsupported())
|
||||
return resultingRepresentation;
|
||||
}
|
||||
|
||||
if (FD->hasThrows() && outputLang == OutputLanguageMode::Cxx)
|
||||
os << ">";
|
||||
os << ' ';
|
||||
if (const auto *typeDecl = modifiers.qualifierContext)
|
||||
ClangSyntaxPrinter(os).printNominalTypeQualifier(
|
||||
@@ -1241,14 +1244,43 @@ void DeclAndTypeClangFunctionPrinter::printCxxThunkBody(
|
||||
// Create the condition and the statement to throw an exception.
|
||||
if (hasThrows) {
|
||||
os << " if (opaqueError != nullptr)\n";
|
||||
os << "#ifdef __cpp_exceptions\n";
|
||||
os << " throw (Swift::Error(opaqueError));\n";
|
||||
}
|
||||
os << "#else\n";
|
||||
if (resultTy->isVoid()) {
|
||||
os << " return SWIFT_RETURN_THUNK(void, Swift::Error(opaqueError));\n";
|
||||
os << "#endif\n";
|
||||
} else {
|
||||
auto directResultType = signature.getDirectResultType();
|
||||
printDirectReturnOrParamCType(
|
||||
*directResultType, resultTy, moduleContext, os, cPrologueOS,
|
||||
typeMapping, interopContext, [&]() {
|
||||
os << " return SWIFT_RETURN_THUNK(";
|
||||
OptionalTypeKind retKind;
|
||||
Type objTy;
|
||||
std::tie(objTy, retKind) =
|
||||
DeclAndTypePrinter::getObjectTypeAndOptionality(FD, resultTy);
|
||||
|
||||
auto s = printClangFunctionReturnType(objTy, retKind, const_cast<ModuleDecl *>(moduleContext),
|
||||
OutputLanguageMode::Cxx);
|
||||
os << ", Swift::Error(opaqueError));\n";
|
||||
os << "#endif\n";
|
||||
|
||||
// Return the function result value if it doesn't throw.
|
||||
if (!resultTy->isVoid() && hasThrows) {
|
||||
os << "\n";
|
||||
os << "return returnValue;\n";
|
||||
os << " return SWIFT_RETURN_THUNK(";
|
||||
printClangFunctionReturnType(
|
||||
objTy, retKind, const_cast<ModuleDecl *>(moduleContext),
|
||||
OutputLanguageMode::Cxx);
|
||||
os << ", returnValue);\n";
|
||||
}
|
||||
|
||||
assert(!s.isUnsupported());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static StringRef getConstructorName(const AbstractFunctionDecl *FD) {
|
||||
|
||||
@@ -166,6 +166,8 @@ inline const void *_Nullable getErrorMetadata() {
|
||||
return ptr2;
|
||||
}
|
||||
|
||||
#ifndef SWIFT_CXX_INTEROP_HIDE_SWIFT_ERROR
|
||||
|
||||
class Error {
|
||||
public:
|
||||
Error() {}
|
||||
@@ -213,4 +215,196 @@ private:
|
||||
void *_Nonnull opaqueValue = nullptr;
|
||||
};
|
||||
|
||||
namespace _impl {
|
||||
|
||||
constexpr inline std::size_t max(std::size_t a, std::size_t b) {
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
} // namespace _impl
|
||||
|
||||
/// The Expected class has either an error or an value.
|
||||
template<class T>
|
||||
class Expected {
|
||||
public:
|
||||
|
||||
/// Default
|
||||
constexpr Expected() noexcept {
|
||||
new (&buffer) Error();
|
||||
has_val = false;
|
||||
}
|
||||
|
||||
constexpr Expected(const Swift::Error& error_val) noexcept {
|
||||
new (&buffer) Error(error_val);
|
||||
has_val = false;
|
||||
}
|
||||
|
||||
constexpr Expected(const T &val) noexcept {
|
||||
new (&buffer) T(val);
|
||||
has_val = true;
|
||||
}
|
||||
|
||||
/// Copy
|
||||
constexpr Expected(Expected const& other) noexcept {
|
||||
if (other.has_value())
|
||||
new (&buffer) T(other.value());
|
||||
else
|
||||
new (&buffer) Error(other.error());
|
||||
|
||||
has_val = other.has_value();
|
||||
}
|
||||
|
||||
/// Move
|
||||
// FIXME: Implement move semantics when move Swift values is possible
|
||||
constexpr Expected(Expected&&) noexcept { abort(); }
|
||||
|
||||
~Expected() noexcept {
|
||||
if (has_value())
|
||||
reinterpret_cast<const T *>(buffer)->~T();
|
||||
else
|
||||
reinterpret_cast<Swift::Error *>(buffer)->~Error();
|
||||
}
|
||||
|
||||
/// assignment
|
||||
constexpr auto operator=(Expected&& other) noexcept = delete;
|
||||
constexpr auto operator=(Expected&) noexcept = delete;
|
||||
|
||||
/// For accessing T's members
|
||||
constexpr T const *_Nonnull operator->() const noexcept {
|
||||
if (!has_value())
|
||||
abort();
|
||||
return reinterpret_cast<const T *>(buffer);
|
||||
}
|
||||
|
||||
constexpr T *_Nonnull operator->() noexcept {
|
||||
if (!has_value())
|
||||
abort();
|
||||
return reinterpret_cast<T *>(buffer);
|
||||
}
|
||||
|
||||
/// Getting reference to T
|
||||
constexpr T const &operator*() const & noexcept {
|
||||
if (!has_value())
|
||||
abort();
|
||||
return reinterpret_cast<const T &>(buffer);
|
||||
}
|
||||
|
||||
constexpr T &operator*() & noexcept {
|
||||
if (!has_value())
|
||||
abort();
|
||||
return reinterpret_cast<T &>(buffer);
|
||||
}
|
||||
|
||||
constexpr explicit operator bool() const noexcept { return has_value(); }
|
||||
|
||||
// Get value, if not exists abort
|
||||
constexpr T const& value() const& {
|
||||
if (!has_value())
|
||||
abort();
|
||||
return *reinterpret_cast<const T *>(buffer);
|
||||
}
|
||||
|
||||
constexpr T& value() & {
|
||||
if (!has_value())
|
||||
abort();
|
||||
return *reinterpret_cast<T *>(buffer);
|
||||
}
|
||||
|
||||
// Get error
|
||||
constexpr Swift::Error const& error() const& {
|
||||
if (has_value())
|
||||
abort();
|
||||
return reinterpret_cast<const Swift::Error&>(buffer);
|
||||
}
|
||||
|
||||
constexpr Swift::Error& error() & {
|
||||
if (has_value())
|
||||
abort();
|
||||
return reinterpret_cast<Swift::Error&>(buffer);
|
||||
}
|
||||
|
||||
constexpr bool has_value() const noexcept { return has_val; }
|
||||
|
||||
private:
|
||||
alignas(_impl::max(alignof(T), alignof(Swift::Error))) char buffer[_impl::max(sizeof(T), sizeof(Swift::Error))];
|
||||
bool has_val;
|
||||
};
|
||||
|
||||
template<>
|
||||
class Expected<void> {
|
||||
public:
|
||||
/// Default
|
||||
Expected() noexcept {
|
||||
new (&buffer) Error();
|
||||
has_val = false;
|
||||
}
|
||||
|
||||
Expected(const Swift::Error& error_val) noexcept {
|
||||
new (&buffer) Error(error_val);
|
||||
has_val = false;
|
||||
}
|
||||
|
||||
|
||||
/// Copy
|
||||
Expected(Expected const& other) noexcept {
|
||||
if (other.has_value())
|
||||
abort();
|
||||
else
|
||||
new (&buffer) Error(other.error());
|
||||
|
||||
has_val = other.has_value();
|
||||
}
|
||||
|
||||
/// Move
|
||||
// FIXME: Implement move semantics when move swift values is possible
|
||||
[[noreturn]] Expected(Expected&&) noexcept { abort(); }
|
||||
|
||||
~Expected() noexcept {
|
||||
reinterpret_cast<Swift::Error *>(buffer)->~Error();
|
||||
}
|
||||
|
||||
/// assignment
|
||||
constexpr auto operator=(Expected&& other) noexcept = delete;
|
||||
constexpr auto operator=(Expected&) noexcept = delete;
|
||||
|
||||
|
||||
constexpr explicit operator bool() const noexcept { return has_value(); }
|
||||
|
||||
// Get error
|
||||
constexpr Swift::Error const& error() const& {
|
||||
if (has_value())
|
||||
abort();
|
||||
return reinterpret_cast<const Swift::Error&>(buffer);
|
||||
}
|
||||
|
||||
constexpr Swift::Error& error() & {
|
||||
if (has_value())
|
||||
abort();
|
||||
return reinterpret_cast<Swift::Error&>(buffer);
|
||||
}
|
||||
|
||||
constexpr bool has_value() const noexcept { return has_val; }
|
||||
private:
|
||||
alignas(alignof(Swift::Error)) char buffer[sizeof(Swift::Error)];
|
||||
bool has_val;
|
||||
};
|
||||
|
||||
#ifdef __cpp_exceptions
|
||||
|
||||
template<class T>
|
||||
using ThrowingResult = T;
|
||||
|
||||
#define SWIFT_RETURN_THUNK(T, v) v
|
||||
|
||||
#else
|
||||
|
||||
template<class T>
|
||||
using ThrowingResult = Swift::Expected<T>;
|
||||
|
||||
#define SWIFT_RETURN_THUNK(T, v) Swift::Expected<T>(v)
|
||||
|
||||
#endif
|
||||
|
||||
#endif // SWIFT_CXX_INTEROP_HIDE_SWIFT_ERROR
|
||||
|
||||
#endif
|
||||
|
||||
118
test/Interop/SwiftToCxx/functions/swift-expected-execution.cpp
Normal file
118
test/Interop/SwiftToCxx/functions/swift-expected-execution.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
|
||||
// RUN: %target-swift-frontend %S/swift-functions-errors.swift -typecheck -module-name Functions -Xcc -fno-exceptions -enable-experimental-cxx-interop -emit-clang-header-path %t/functions.h
|
||||
|
||||
// RUN: %target-interop-build-clangxx -c %s -I %t -fno-exceptions -o %t/swift-expected-execution.o
|
||||
// RUN: %target-interop-build-swift %S/swift-functions-errors.swift -o %t/swift-expected-execution -Xlinker %t/swift-expected-execution.o -module-name Functions -Xfrontend -entry-point-function-name -Xfrontend swiftMain
|
||||
|
||||
// RUN: %target-codesign %t/swift-expected-execution
|
||||
// RUN: %target-run %t/swift-expected-execution | %FileCheck %s
|
||||
|
||||
// REQUIRES: executable_test
|
||||
// UNSUPPORTED: OS=windows-msvc
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include "functions.h"
|
||||
|
||||
int main() {
|
||||
|
||||
// Test Empty Constructor
|
||||
auto testIntEmpty = Swift::Expected<int>();
|
||||
|
||||
// Test Error Constructor
|
||||
Swift::Error e;
|
||||
auto testIntError = Swift::Expected<int>(e);
|
||||
|
||||
// Test Value Constructor
|
||||
auto testIntValue = Swift::Expected<int>(42);
|
||||
|
||||
// Test Copy Constructor
|
||||
auto testCopy = testIntEmpty;
|
||||
|
||||
// TODO: Test Move Constructor
|
||||
|
||||
// Test Destructor
|
||||
auto testDestEmpty = Swift::Expected<int>();
|
||||
auto testDestInt = Swift::Expected<int>(42);
|
||||
auto testDestError = Swift::Expected<int>(e);
|
||||
testDestEmpty.~Expected();
|
||||
testDestInt.~Expected();
|
||||
testDestError.~Expected();
|
||||
|
||||
// TODO: Test Assignment (Move)
|
||||
|
||||
// Test Access to T's members (const)
|
||||
const auto exp = testIntValue;
|
||||
if (*exp.operator->() == 42)
|
||||
printf("Test Access to T's members (const)\n");
|
||||
|
||||
// Test Access to T's members
|
||||
if (*testIntValue.operator->() == 42)
|
||||
printf("Test Access to T's members\n");
|
||||
|
||||
// Test Reference to T's members (const)
|
||||
const auto refExp = testIntValue;
|
||||
if (*refExp == 42)
|
||||
printf("Test Reference to T's members (const)\n");
|
||||
|
||||
// Test Reference to T's members
|
||||
if (*testIntValue == 42)
|
||||
printf("Test Reference to T's members\n");
|
||||
|
||||
// Test bool operator
|
||||
if (testIntValue) {
|
||||
printf("Test operator bool\n");
|
||||
}
|
||||
|
||||
const auto constExpectedResult = Functions::throwFunctionWithPossibleReturn(0);
|
||||
if (!constExpectedResult.has_value()) {
|
||||
auto constError = constExpectedResult.error();
|
||||
auto optionalError = constError.as<Functions::NaiveErrors>();
|
||||
assert(optionalError.isSome());
|
||||
auto valueError = optionalError.get();
|
||||
assert(valueError == Functions::NaiveErrors::returnError);
|
||||
valueError.getMessage();
|
||||
}
|
||||
|
||||
auto expectedResult = Functions::throwFunctionWithPossibleReturn(0);
|
||||
if (!expectedResult.has_value()) {
|
||||
auto error = expectedResult.error();
|
||||
auto optionalError = error.as<Functions::NaiveErrors>();
|
||||
assert(optionalError.isSome());
|
||||
auto valueError = optionalError.get();
|
||||
assert(valueError == Functions::NaiveErrors::returnError);
|
||||
valueError.getMessage();
|
||||
}
|
||||
|
||||
// Test get T's Value (const)
|
||||
const auto valueExp = testIntValue;
|
||||
if (valueExp.value() == 42)
|
||||
printf("Test get T's Value (const)\n");
|
||||
|
||||
// Test get T's Value
|
||||
if (testIntValue.value() == 42)
|
||||
printf("Test get T's Value\n");
|
||||
|
||||
// Test has Value
|
||||
if (testIntValue.has_value())
|
||||
printf("testIntValue has a value\n");
|
||||
if (!testIntError.has_value())
|
||||
printf("testIntError doesn't have a value\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// CHECK: Test Access to T's members (const)
|
||||
// CHECK-NEXT: Test Access to T's members
|
||||
// CHECK-NEXT: Test Reference to T's members (const)
|
||||
// CHECK-NEXT: Test Reference to T's members
|
||||
// CHECK-NEXT: Test operator bool
|
||||
// CHECK-NEXT: passThrowFunctionWithPossibleReturn
|
||||
// CHECK-NEXT: returnError
|
||||
// CHECK-NEXT: passThrowFunctionWithPossibleReturn
|
||||
// CHECK-NEXT: returnError
|
||||
// CHECK-NEXT: Test get T's Value (const)
|
||||
// CHECK-NEXT: Test get T's Value
|
||||
// CHECK-NEXT: testIntValue has a value
|
||||
// CHECK-NEXT: testIntError doesn't have a value
|
||||
@@ -9,7 +9,11 @@
|
||||
// CHECK-LABEL: namespace _impl {
|
||||
|
||||
// CHECK: SWIFT_EXTERN void $s9Functions18emptyThrowFunctionyyKF(SWIFT_CONTEXT void * _Nonnull _ctx, SWIFT_ERROR_RESULT void * _Nullable * _Nullable _error) SWIFT_CALL; // emptyThrowFunction()
|
||||
// CHECK: SWIFT_EXTERN void $s9Functions18testDestroyedErroryyKF(SWIFT_CONTEXT void * _Nonnull _ctx, SWIFT_ERROR_RESULT void * _Nullable * _Nullable _error) SWIFT_CALL; // testDestroyedError()
|
||||
// CHECK: SWIFT_EXTERN void $s9Functions13throwFunctionyyKF(SWIFT_CONTEXT void * _Nonnull _ctx, SWIFT_ERROR_RESULT void * _Nullable * _Nullable _error) SWIFT_CALL; // throwFunction()
|
||||
// CHECK: SWIFT_EXTERN ptrdiff_t $s9Functions31throwFunctionWithPossibleReturnyS2iKF(ptrdiff_t a, SWIFT_CONTEXT void * _Nonnull _ctx, SWIFT_ERROR_RESULT void * _Nullable * _Nullable _error) SWIFT_CALL; // throwFunctionWithPossibleReturn(_:)
|
||||
// CHECK: SWIFT_EXTERN ptrdiff_t $s9Functions23throwFunctionWithReturnSiyKF(SWIFT_CONTEXT void * _Nonnull _ctx, SWIFT_ERROR_RESULT void * _Nullable * _Nullable _error) SWIFT_CALL; // throwFunctionWithReturn()
|
||||
|
||||
|
||||
// CHECK: }
|
||||
|
||||
@@ -26,12 +30,16 @@ public enum NaiveErrors : Error {
|
||||
@_expose(Cxx)
|
||||
public func emptyThrowFunction() throws { print("passEmptyThrowFunction") }
|
||||
|
||||
// CHECK: inline void emptyThrowFunction() {
|
||||
// CHECK: inline Swift::ThrowingResult<void> emptyThrowFunction() {
|
||||
// CHECK: void* opaqueError = nullptr;
|
||||
// CHECK: void* _ctx = nullptr;
|
||||
// CHECK: _impl::$s9Functions18emptyThrowFunctionyyKF(_ctx, &opaqueError);
|
||||
// CHECK: if (opaqueError != nullptr)
|
||||
// CHECK: throw (Swift::Error(opaqueError))
|
||||
// CHECK: #ifdef __cpp_exceptions
|
||||
// CHECK: throw (Swift::Error(opaqueError));
|
||||
// CHECK: #else
|
||||
// CHECK: return SWIFT_RETURN_THUNK(void, Swift::Error(opaqueError));
|
||||
// CHECK: #endif
|
||||
// CHECK: }
|
||||
|
||||
class TestDestroyed {
|
||||
@@ -48,12 +56,16 @@ public struct DestroyedError : Error {
|
||||
@_expose(Cxx)
|
||||
public func testDestroyedError() throws { throw DestroyedError() }
|
||||
|
||||
// CHECK: inline void testDestroyedError() {
|
||||
// CHECK: inline Swift::ThrowingResult<void> testDestroyedError() {
|
||||
// CHECK: void* opaqueError = nullptr;
|
||||
// CHECK: void* _ctx = nullptr;
|
||||
// CHECK: _impl::$s9Functions18testDestroyedErroryyKF(_ctx, &opaqueError);
|
||||
// CHECK: if (opaqueError != nullptr)
|
||||
// CHECK: throw (Swift::Error(opaqueError))
|
||||
// CHECK: #ifdef __cpp_exceptions
|
||||
// CHECK: throw (Swift::Error(opaqueError));
|
||||
// CHECK: #else
|
||||
// CHECK: return SWIFT_RETURN_THUNK(void, Swift::Error(opaqueError));
|
||||
// CHECK: #endif
|
||||
// CHECK: }
|
||||
|
||||
@_expose(Cxx)
|
||||
@@ -62,12 +74,38 @@ public func throwFunction() throws {
|
||||
throw NaiveErrors.throwError
|
||||
}
|
||||
|
||||
// CHECK: inline void throwFunction() {
|
||||
// CHECK: inline Swift::ThrowingResult<void> throwFunction() {
|
||||
// CHECK: void* opaqueError = nullptr;
|
||||
// CHECK: void* _ctx = nullptr;
|
||||
// CHECK: _impl::$s9Functions13throwFunctionyyKF(_ctx, &opaqueError);
|
||||
// CHECK: if (opaqueError != nullptr)
|
||||
// CHECK: throw (Swift::Error(opaqueError))
|
||||
// CHECK: #ifdef __cpp_exceptions
|
||||
// CHECK: throw (Swift::Error(opaqueError));
|
||||
// CHECK: #else
|
||||
// CHECK: return SWIFT_RETURN_THUNK(void, Swift::Error(opaqueError));
|
||||
// CHECK: #endif
|
||||
// CHECK: }
|
||||
|
||||
@_expose(Cxx)
|
||||
public func throwFunctionWithPossibleReturn(_ a: Int) throws -> Int {
|
||||
print("passThrowFunctionWithPossibleReturn")
|
||||
if (a == 0) {
|
||||
throw NaiveErrors.returnError
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// CHECK: inline Swift::ThrowingResult<swift::Int> throwFunctionWithPossibleReturn(swift::Int a) SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK: void* opaqueError = nullptr;
|
||||
// CHECK: void* _ctx = nullptr;
|
||||
// CHECK: auto returnValue = _impl::$s9Functions31throwFunctionWithPossibleReturnyS2iKF(a, _ctx, &opaqueError);
|
||||
// CHECK: if (opaqueError != nullptr)
|
||||
// CHECK: #ifdef __cpp_exceptions
|
||||
// CHECK: throw (Swift::Error(opaqueError));
|
||||
// CHECK: #else
|
||||
// CHECK: return SWIFT_RETURN_THUNK(swift::Int, Swift::Error(opaqueError));
|
||||
// CHECK: #endif
|
||||
// CHECK: return SWIFT_RETURN_THUNK(swift::Int, returnValue);
|
||||
// CHECK: }
|
||||
|
||||
@_expose(Cxx)
|
||||
@@ -77,11 +115,14 @@ public func throwFunctionWithReturn() throws -> Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
// CHECK: inline swift::Int throwFunctionWithReturn() SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK: inline Swift::ThrowingResult<swift::Int> throwFunctionWithReturn() SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK: void* opaqueError = nullptr;
|
||||
// CHECK: void* _ctx = nullptr;
|
||||
// CHECK: auto returnValue = _impl::$s9Functions23throwFunctionWithReturnSiyKF(_ctx, &opaqueError);
|
||||
// CHECK: if (opaqueError != nullptr)
|
||||
// CHECK: throw (Swift::Error(opaqueError))
|
||||
// CHECK: return returnValue;
|
||||
// CHECK: #ifdef __cpp_exceptions
|
||||
// CHECK: throw (Swift::Error(opaqueError));
|
||||
// CHECK: #else
|
||||
// CHECK: return SWIFT_RETURN_THUNK(swift::Int, Swift::Error(opaqueError));
|
||||
// CHECK: #endif
|
||||
// CHECK: return SWIFT_RETURN_THUNK(swift::Int, returnValue);
|
||||
// CHECK: }
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: split-file %s %t
|
||||
|
||||
// RUN: touch %t/swiftMod.h
|
||||
// RUN: %target-swift-frontend -typecheck %t/swiftMod.swift -typecheck -module-name SwiftMod -emit-clang-header-path %t/swiftMod.h -I %t -enable-experimental-cxx-interop
|
||||
// RUN: %target-swift-frontend -typecheck %t/swiftMod.swift -typecheck -module-name SwiftMod -emit-clang-header-path %t/swiftMod.h -I %t -enable-experimental-cxx-interop -Xcc -DFIRSTPASS
|
||||
|
||||
// RUN: %FileCheck %s < %t/swiftMod.h
|
||||
|
||||
// RUN: %target-swift-frontend -typecheck %t/swiftMod.swift -typecheck -module-name SwiftMod -emit-clang-header-path %t/swiftMod2.h -I %t -enable-experimental-cxx-interop
|
||||
// RUN: %target-swift-frontend -typecheck %t/swiftMod.swift -typecheck -module-name SwiftMod -emit-clang-header-path %t/swiftMod2.h -I %t -enable-experimental-cxx-interop -Xcc -DSWIFT_CXX_INTEROP_HIDE_SWIFT_ERROR
|
||||
|
||||
// RUN: %check-interop-cxx-header-in-clang(%t/swiftMod2.h -DSWIFT_CXX_INTEROP_HIDE_STL_OVERLAY -Wno-error)
|
||||
|
||||
// XFAIL: OS=linux-android, OS=linux-androideabi
|
||||
|
||||
//--- header.h
|
||||
#ifndef FIRSTPASS
|
||||
#include "swiftMod.h"
|
||||
#endif
|
||||
|
||||
//--- module.modulemap
|
||||
module SwiftToCxxTest {
|
||||
|
||||
Reference in New Issue
Block a user