mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[cxx-interop] Emit C++ inline function thunks that with correct primitive types
This commit is contained in:
@@ -716,8 +716,7 @@ private:
|
||||
/// Print the core function declaration for a given function with the given
|
||||
/// name.
|
||||
void printFunctionDeclAsCFunctionDecl(FuncDecl *FD, StringRef name,
|
||||
Type resultTy,
|
||||
bool printEmptyParamNames = false) {
|
||||
Type resultTy) {
|
||||
// The result type may be a partial function type we need to close
|
||||
// up later.
|
||||
PrintMultiPartType multiPart(*this);
|
||||
@@ -737,12 +736,8 @@ private:
|
||||
Type objTy;
|
||||
std::tie(objTy, kind) =
|
||||
getObjectTypeAndOptionality(param, param->getInterfaceType());
|
||||
std::string paramName =
|
||||
param->getName().empty() ? "" : param->getName().str().str();
|
||||
if (printEmptyParamNames && paramName.empty()) {
|
||||
llvm::raw_string_ostream os(paramName);
|
||||
os << "_" << index;
|
||||
}
|
||||
StringRef paramName =
|
||||
param->getName().empty() ? "" : param->getName().str();
|
||||
print(objTy, kind, paramName, IsFunctionParam);
|
||||
++index;
|
||||
});
|
||||
@@ -868,9 +863,9 @@ private:
|
||||
getForeignResultType(FD, funcTy, asyncConvention, errorConvention);
|
||||
|
||||
os << "inline ";
|
||||
printFunctionDeclAsCFunctionDecl(FD,
|
||||
FD->getName().getBaseIdentifier().get(),
|
||||
resultTy, /*printEmptyParamNames=*/true);
|
||||
DeclAndTypeClangFunctionPrinter funcPrinter(os, owningPrinter.typeMapping);
|
||||
funcPrinter.printFunctionDeclAsCxxFunctionDecl(
|
||||
FD, FD->getName().getBaseIdentifier().get(), resultTy);
|
||||
// FIXME: Support throwing exceptions for Swift errors.
|
||||
os << " noexcept";
|
||||
printFunctionClangAttributes(FD, funcTy);
|
||||
@@ -1998,7 +1993,7 @@ private:
|
||||
/// visitPart().
|
||||
public:
|
||||
void print(Type ty, Optional<OptionalTypeKind> optionalKind,
|
||||
std::string name = "",
|
||||
StringRef name = "",
|
||||
IsFunctionParam_t isFuncParam = IsNotFunctionParam) {
|
||||
PrettyStackTraceType trace(getASTContext(), "printing", ty);
|
||||
|
||||
|
||||
@@ -24,11 +24,20 @@ void PrimitiveTypeMapping::initialize(ASTContext &ctx) {
|
||||
mappedTypeNames[{ctx.StdlibModuleName, ctx.getIdentifier(#SWIFT_NAME)}] = { \
|
||||
CLANG_REPR, \
|
||||
Optional<StringRef>(CLANG_REPR), \
|
||||
Optional<StringRef>(CLANG_REPR), \
|
||||
NEEDS_NULLABILITY \
|
||||
}
|
||||
#define MAP_C(SWIFT_NAME, OBJC_REPR, C_REPR, NEEDS_NULLABILITY) \
|
||||
mappedTypeNames[{ctx.StdlibModuleName, ctx.getIdentifier(#SWIFT_NAME)}] = { \
|
||||
OBJC_REPR, Optional<StringRef>(C_REPR), NEEDS_NULLABILITY}
|
||||
OBJC_REPR, \
|
||||
Optional<StringRef>(C_REPR), \
|
||||
Optional<StringRef>(C_REPR), \
|
||||
NEEDS_NULLABILITY \
|
||||
}
|
||||
#define MAP_CXX(SWIFT_NAME, OBJC_REPR, C_REPR, CXX_REPR, NEEDS_NULLABILITY) \
|
||||
mappedTypeNames[{ctx.StdlibModuleName, ctx.getIdentifier(#SWIFT_NAME)}] = { \
|
||||
OBJC_REPR, Optional<StringRef>(C_REPR), Optional<StringRef>(CXX_REPR), \
|
||||
NEEDS_NULLABILITY}
|
||||
|
||||
MAP(CBool, "bool", false);
|
||||
|
||||
@@ -66,8 +75,8 @@ void PrimitiveTypeMapping::initialize(ASTContext &ctx) {
|
||||
MAP(Float32, "float", false);
|
||||
MAP(Float64, "double", false);
|
||||
|
||||
MAP_C(Int, "NSInteger", "ptrdiff_t", false);
|
||||
MAP_C(UInt, "NSUInteger", "size_t", false);
|
||||
MAP_CXX(Int, "NSInteger", "ptrdiff_t", "swift::Int", false);
|
||||
MAP_CXX(UInt, "NSUInteger", "size_t", "swift::UInt", false);
|
||||
MAP_C(Bool, "BOOL", "bool", false);
|
||||
|
||||
MAP(OpaquePointer, "void *", true);
|
||||
@@ -76,33 +85,33 @@ void PrimitiveTypeMapping::initialize(ASTContext &ctx) {
|
||||
|
||||
Identifier ID_ObjectiveC = ctx.Id_ObjectiveC;
|
||||
mappedTypeNames[{ID_ObjectiveC, ctx.getIdentifier("ObjCBool")}] = {
|
||||
"BOOL", None, false};
|
||||
"BOOL", None, None, false};
|
||||
mappedTypeNames[{ID_ObjectiveC, ctx.getIdentifier("Selector")}] = {
|
||||
"SEL", None, true};
|
||||
"SEL", None, None, true};
|
||||
mappedTypeNames[{ID_ObjectiveC, ctx.getIdentifier(ctx.getSwiftName(
|
||||
KnownFoundationEntity::NSZone))}] = {
|
||||
"struct _NSZone *", None, true};
|
||||
"struct _NSZone *", None, None, true};
|
||||
|
||||
mappedTypeNames[{ctx.Id_Darwin, ctx.getIdentifier("DarwinBoolean")}] = {
|
||||
"Boolean", None, false};
|
||||
"Boolean", None, None, false};
|
||||
|
||||
mappedTypeNames[{ctx.Id_CoreGraphics, ctx.Id_CGFloat}] = {"CGFloat", None,
|
||||
false};
|
||||
None, false};
|
||||
|
||||
mappedTypeNames[{ctx.Id_CoreFoundation, ctx.Id_CGFloat}] = {"CGFloat", None,
|
||||
false};
|
||||
None, false};
|
||||
|
||||
// Use typedefs we set up for SIMD vector types.
|
||||
#define MAP_SIMD_TYPE(BASENAME, _, __) \
|
||||
StringRef simd2##BASENAME = "swift_" #BASENAME "2"; \
|
||||
mappedTypeNames[{ctx.Id_simd, ctx.getIdentifier(#BASENAME "2")}] = { \
|
||||
"swift_" #BASENAME "2", Optional<StringRef>("swift_" #BASENAME "2"), \
|
||||
false}; \
|
||||
simd2##BASENAME, simd2##BASENAME, simd2##BASENAME, false}; \
|
||||
StringRef simd3##BASENAME = "swift_" #BASENAME "3"; \
|
||||
mappedTypeNames[{ctx.Id_simd, ctx.getIdentifier(#BASENAME "3")}] = { \
|
||||
"swift_" #BASENAME "3", Optional<StringRef>("swift_" #BASENAME "3"), \
|
||||
false}; \
|
||||
simd3##BASENAME, simd3##BASENAME, simd3##BASENAME, false}; \
|
||||
StringRef simd4##BASENAME = "swift_" #BASENAME "4"; \
|
||||
mappedTypeNames[{ctx.Id_simd, ctx.getIdentifier(#BASENAME "4")}] = { \
|
||||
"swift_" #BASENAME "4", Optional<StringRef>("swift_" #BASENAME "4"), \
|
||||
false};
|
||||
simd4##BASENAME, simd4##BASENAME, simd4##BASENAME, false};
|
||||
#include "swift/ClangImporter/SIMDMappedTypes.def"
|
||||
static_assert(SWIFT_MAX_IMPORTED_SIMD_ELEMENTS == 4,
|
||||
"must add or remove special name mappings if max number of "
|
||||
@@ -137,3 +146,12 @@ PrimitiveTypeMapping::getKnownCTypeInfo(const TypeDecl *typeDecl) {
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
Optional<PrimitiveTypeMapping::CxxClangTypeInfo>
|
||||
PrimitiveTypeMapping::getKnownCxxTypeInfo(const TypeDecl *typeDecl) {
|
||||
if (auto *typeInfo = getMappedTypeInfoOrNull(typeDecl)) {
|
||||
if (typeInfo->cxxName)
|
||||
return CxxClangTypeInfo{*typeInfo->cxxName, typeInfo->canBeNullable};
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,15 @@ public:
|
||||
/// primitive type declaration, or \c None if no such type name exists.
|
||||
Optional<CClangTypeInfo> getKnownCTypeInfo(const TypeDecl *typeDecl);
|
||||
|
||||
struct CxxClangTypeInfo {
|
||||
StringRef name;
|
||||
bool canBeNullable;
|
||||
};
|
||||
|
||||
/// Returns the C++ type name and nullability for the given Swift
|
||||
/// primitive type declaration, or \c None if no such type name exists.
|
||||
Optional<CxxClangTypeInfo> getKnownCxxTypeInfo(const TypeDecl *typeDecl);
|
||||
|
||||
private:
|
||||
void initialize(ASTContext &ctx);
|
||||
|
||||
@@ -56,6 +65,8 @@ private:
|
||||
StringRef objcName;
|
||||
// The C name of the Swift type.
|
||||
Optional<StringRef> cName;
|
||||
// The C++ name of the Swift type.
|
||||
Optional<StringRef> cxxName;
|
||||
bool canBeNullable;
|
||||
};
|
||||
|
||||
|
||||
@@ -304,6 +304,15 @@ static void writePrologue(raw_ostream &out, ASTContext &ctx,
|
||||
emitCxxConditional(
|
||||
out, [&] { emitMacro("SWIFT_NOEXCEPT", "noexcept"); },
|
||||
[&] { emitMacro("SWIFT_NOEXCEPT"); });
|
||||
emitCxxConditional(out, [&] {
|
||||
out << "#if !defined(SWIFT_CXX_INT_DEFINED)\n";
|
||||
out << "#define SWIFT_CXX_INT_DEFINED\n";
|
||||
out << "namespace swift {\n";
|
||||
out << "using Int = ptrdiff_t;\n";
|
||||
out << "using UInt = size_t;\n";
|
||||
out << "}\n";
|
||||
out << "#endif\n";
|
||||
});
|
||||
static_assert(SWIFT_MAX_IMPORTED_SIMD_ELEMENTS == 4,
|
||||
"need to add SIMD typedefs here if max elements is increased");
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "PrintClangFunction.h"
|
||||
#include "ClangSyntaxPrinter.h"
|
||||
#include "DeclAndTypePrinter.h"
|
||||
#include "OutputLanguageMode.h"
|
||||
#include "PrimitiveTypeMapping.h"
|
||||
#include "swift/AST/Decl.h"
|
||||
#include "swift/AST/ParameterList.h"
|
||||
@@ -23,6 +24,22 @@
|
||||
|
||||
using namespace swift;
|
||||
|
||||
namespace {
|
||||
|
||||
class ClangFunctionSignatureTypePrinter : private ClangSyntaxPrinter {
|
||||
public:
|
||||
ClangFunctionSignatureTypePrinter(raw_ostream &os) : ClangSyntaxPrinter(os) {}
|
||||
|
||||
void printIfSimpleType(StringRef name, bool canBeNullable,
|
||||
Optional<OptionalTypeKind> optionalKind) {
|
||||
os << name;
|
||||
if (canBeNullable)
|
||||
printNullability(optionalKind);
|
||||
}
|
||||
|
||||
void printVoidType() { os << "void"; }
|
||||
};
|
||||
|
||||
// Prints types in the C function signature that corresponds to the
|
||||
// native Swift function/method.
|
||||
class CFunctionSignatureTypePrinter
|
||||
@@ -31,11 +48,22 @@ class CFunctionSignatureTypePrinter
|
||||
private ClangSyntaxPrinter {
|
||||
public:
|
||||
CFunctionSignatureTypePrinter(raw_ostream &os,
|
||||
PrimitiveTypeMapping &typeMapping)
|
||||
: ClangSyntaxPrinter(os), typeMapping(typeMapping) {}
|
||||
PrimitiveTypeMapping &typeMapping,
|
||||
OutputLanguageMode languageMode)
|
||||
: ClangSyntaxPrinter(os), typeMapping(typeMapping),
|
||||
languageMode(languageMode) {}
|
||||
|
||||
bool printIfKnownSimpleType(const TypeDecl *typeDecl,
|
||||
Optional<OptionalTypeKind> optionalKind) {
|
||||
if (languageMode == OutputLanguageMode::Cxx) {
|
||||
auto knownTypeInfo = typeMapping.getKnownCxxTypeInfo(typeDecl);
|
||||
if (!knownTypeInfo)
|
||||
return false;
|
||||
os << knownTypeInfo->name;
|
||||
if (knownTypeInfo->canBeNullable)
|
||||
printNullability(optionalKind);
|
||||
return true;
|
||||
}
|
||||
auto knownTypeInfo = typeMapping.getKnownCTypeInfo(typeDecl);
|
||||
if (!knownTypeInfo)
|
||||
return false;
|
||||
@@ -83,8 +111,11 @@ public:
|
||||
|
||||
private:
|
||||
PrimitiveTypeMapping &typeMapping;
|
||||
OutputLanguageMode languageMode;
|
||||
};
|
||||
|
||||
} // end namespace
|
||||
|
||||
void DeclAndTypeClangFunctionPrinter::printFunctionDeclAsCFunctionDecl(
|
||||
FuncDecl *FD, StringRef name, Type resultTy) {
|
||||
// FIXME: Might need a PrintMultiPartType here.
|
||||
@@ -92,7 +123,8 @@ void DeclAndTypeClangFunctionPrinter::printFunctionDeclAsCFunctionDecl(
|
||||
StringRef name) {
|
||||
// FIXME: add support for noescape and PrintMultiPartType,
|
||||
// see DeclAndTypePrinter::print.
|
||||
CFunctionSignatureTypePrinter typePrinter(os, typeMapping);
|
||||
CFunctionSignatureTypePrinter typePrinter(os, typeMapping,
|
||||
OutputLanguageMode::ObjC);
|
||||
typePrinter.visit(ty, optionalKind);
|
||||
|
||||
if (!name.empty()) {
|
||||
@@ -106,7 +138,8 @@ void DeclAndTypeClangFunctionPrinter::printFunctionDeclAsCFunctionDecl(
|
||||
Type objTy;
|
||||
std::tie(objTy, kind) =
|
||||
DeclAndTypePrinter::getObjectTypeAndOptionality(FD, resultTy);
|
||||
CFunctionSignatureTypePrinter typePrinter(os, typeMapping);
|
||||
CFunctionSignatureTypePrinter typePrinter(os, typeMapping,
|
||||
OutputLanguageMode::ObjC);
|
||||
typePrinter.visit(objTy, kind);
|
||||
|
||||
os << ' ' << name << '(';
|
||||
@@ -128,3 +161,53 @@ void DeclAndTypeClangFunctionPrinter::printFunctionDeclAsCFunctionDecl(
|
||||
}
|
||||
os << ')';
|
||||
}
|
||||
|
||||
void DeclAndTypeClangFunctionPrinter::printFunctionDeclAsCxxFunctionDecl(
|
||||
FuncDecl *FD, StringRef name, Type resultTy) {
|
||||
// FIXME: Might need a PrintMultiPartType here.
|
||||
auto print = [this](Type ty, Optional<OptionalTypeKind> optionalKind,
|
||||
StringRef name) {
|
||||
// FIXME: add support for noescape and PrintMultiPartType,
|
||||
// see DeclAndTypePrinter::print.
|
||||
CFunctionSignatureTypePrinter typePrinter(os, typeMapping,
|
||||
OutputLanguageMode::Cxx);
|
||||
typePrinter.visit(ty, optionalKind);
|
||||
|
||||
if (!name.empty()) {
|
||||
os << ' ';
|
||||
ClangSyntaxPrinter(os).printIdentifier(name);
|
||||
}
|
||||
};
|
||||
|
||||
// Print out the return type.
|
||||
OptionalTypeKind kind;
|
||||
Type objTy;
|
||||
std::tie(objTy, kind) =
|
||||
DeclAndTypePrinter::getObjectTypeAndOptionality(FD, resultTy);
|
||||
CFunctionSignatureTypePrinter typePrinter(os, typeMapping,
|
||||
OutputLanguageMode::Cxx);
|
||||
typePrinter.visit(objTy, kind);
|
||||
|
||||
os << ' ' << name << '(';
|
||||
|
||||
// Print out the parameter types.
|
||||
auto params = FD->getParameters();
|
||||
if (params->size()) {
|
||||
size_t paramIndex = 1;
|
||||
llvm::interleaveComma(*params, os, [&](const ParamDecl *param) {
|
||||
OptionalTypeKind kind;
|
||||
Type objTy;
|
||||
std::tie(objTy, kind) = DeclAndTypePrinter::getObjectTypeAndOptionality(
|
||||
param, param->getInterfaceType());
|
||||
std::string paramName =
|
||||
param->getName().empty() ? "" : param->getName().str().str();
|
||||
if (paramName.empty()) {
|
||||
llvm::raw_string_ostream os(paramName);
|
||||
os << "_" << paramIndex;
|
||||
}
|
||||
print(objTy, kind, paramName);
|
||||
++paramIndex;
|
||||
});
|
||||
}
|
||||
os << ')';
|
||||
}
|
||||
|
||||
@@ -36,6 +36,11 @@ public:
|
||||
void printFunctionDeclAsCFunctionDecl(FuncDecl *FD, StringRef name,
|
||||
Type resultTy);
|
||||
|
||||
/// Print the inline C++ function thunk declaration that corresponds to the
|
||||
/// given Swift function declaration.
|
||||
void printFunctionDeclAsCxxFunctionDecl(FuncDecl *FD, StringRef name,
|
||||
Type resultTy);
|
||||
|
||||
private:
|
||||
raw_ostream &os;
|
||||
PrimitiveTypeMapping &typeMapping;
|
||||
|
||||
@@ -16,22 +16,22 @@
|
||||
|
||||
// CHECK: }
|
||||
|
||||
// CHECK: inline void alwaysDeprecated(void) noexcept SWIFT_DEPRECATED {
|
||||
// CHECK: inline void alwaysDeprecated() noexcept SWIFT_DEPRECATED {
|
||||
@available(*, deprecated)
|
||||
public func alwaysDeprecated() {}
|
||||
|
||||
// CHECK: inline void alwaysDeprecatedTwo(void) noexcept SWIFT_DEPRECATED_MSG("it should not be used")
|
||||
// CHECK: inline void alwaysDeprecatedTwo() noexcept SWIFT_DEPRECATED_MSG("it should not be used")
|
||||
@available(*, deprecated, message: "it should not be used")
|
||||
public func alwaysDeprecatedTwo() {}
|
||||
|
||||
// CHECK: inline void alwaysUnavailable(void) noexcept SWIFT_UNAVAILABLE
|
||||
// CHECK: inline void alwaysUnavailable() noexcept SWIFT_UNAVAILABLE
|
||||
@available(*, unavailable)
|
||||
public func alwaysUnavailable() {}
|
||||
|
||||
// CHECK: inline void alwaysUnavailableMessage(void) noexcept SWIFT_UNAVAILABLE_MSG("stuff happened")
|
||||
// CHECK: inline void alwaysUnavailableMessage() noexcept SWIFT_UNAVAILABLE_MSG("stuff happened")
|
||||
@available(*, unavailable, message: "stuff happened")
|
||||
public func alwaysUnavailableMessage() {}
|
||||
|
||||
// CHECK: inline void singlePlatAvailability(void) noexcept SWIFT_AVAILABILITY(macos,introduced=11)
|
||||
// CHECK: inline void singlePlatAvailability() noexcept SWIFT_AVAILABILITY(macos,introduced=11)
|
||||
@available(macOS 11, *)
|
||||
public func singlePlatAvailability() {}
|
||||
|
||||
@@ -45,6 +45,6 @@ public func passTwoIntReturnIntNoArgLabelParamName(_ x2: CInt, _ y2: CInt) -> CI
|
||||
|
||||
public func passVoidReturnVoid() { print("passVoidReturnVoid") }
|
||||
|
||||
// CHECK: inline void passVoidReturnVoid(void) noexcept {
|
||||
// CHECK: inline void passVoidReturnVoid() noexcept {
|
||||
// CHECK: return _impl::$s9Functions014passVoidReturnC0yyF();
|
||||
// CHECK: }
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-swift-frontend %s -typecheck -module-name Functions -clang-header-expose-public-decls -emit-clang-header-path %t/functions.h
|
||||
// RUN: %FileCheck %s < %t/functions.h
|
||||
|
||||
// RUN: %check-interop-cxx-header-in-clang(%t/functions.h)
|
||||
|
||||
// CHECK: inline float passThrougCFloat(float x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions16passThrougCFloatyS2fF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline bool passThroughBool(bool x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions15passThroughBoolyS2bF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline bool passThroughCBool(bool x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions16passThroughCBoolyS2bF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline char passThroughCChar(char x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions16passThroughCCharys4Int8VADF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline char16_t passThroughCChar16(char16_t x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions18passThroughCChar16ys6UInt16VADF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline char32_t passThroughCChar32(char32_t x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions18passThroughCChar32ys7UnicodeO6ScalarVAFF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline double passThroughCDouble(double x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions18passThroughCDoubleyS2dF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline int passThroughCInt(int x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions15passThroughCIntys5Int32VADF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline long long passThroughCLongLong(long long x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions20passThroughCLongLongys5Int64VADF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline short passThroughCShort(short x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions17passThroughCShortys5Int16VADF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline signed char passThroughCSignedChar(signed char x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions22passThroughCSignedCharys4Int8VADF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
|
||||
// CHECK: inline unsigned int passThroughCUnsignedInt(unsigned int x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions23passThroughCUnsignedIntys6UInt32VADF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline unsigned long long passThroughCUnsignedLongLong(unsigned long long x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions024passThroughCUnsignedLongE0ys6UInt64VADF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
|
||||
// CHECK: inline unsigned short passThroughCUnsignedShort(unsigned short x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions25passThroughCUnsignedShortys6UInt16VADF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline unsigned char passThroughCUnsignedSignedChar(unsigned char x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions30passThroughCUnsignedSignedCharys5UInt8VADF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline wchar_t passThroughCWideChar(wchar_t x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions20passThroughCWideCharys7UnicodeO6ScalarVAFF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline double passThroughDouble(double x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions17passThroughDoubleyS2dF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline float passThroughFloat(float x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions16passThroughFloatyS2fF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline float passThroughFloat32(float x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions18passThroughFloat32yS2fF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline double passThroughFloat64(double x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions18passThroughFloat64yS2dF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline swift::Int passThroughInt(swift::Int x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions14passThroughIntyS2iF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline int16_t passThroughInt16(int16_t x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions16passThroughInt16ys0D0VADF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline int32_t passThroughInt32(int32_t x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions16passThroughInt32ys0D0VADF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline int64_t passThroughInt64(int64_t x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions16passThroughInt64ys0D0VADF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline int8_t passThroughInt8(int8_t x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions15passThroughInt8ys0D0VADF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline void * _Nonnull passThroughOpaquePointer(void * _Nonnull x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions24passThroughOpaquePointerys0dE0VADF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline swift::UInt passThroughUInt(swift::UInt x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions15passThroughUIntyS2uF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline uint16_t passThroughUInt16(uint16_t x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions17passThroughUInt16ys0D0VADF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline uint32_t passThroughUInt32(uint32_t x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions17passThroughUInt32ys0D0VADF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline uint64_t passThroughUInt64(uint64_t x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions17passThroughUInt64ys0D0VADF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
|
||||
// CHECK: inline uint8_t passThroughUInt8(uint8_t x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions16passThroughUInt8ys0D0VADF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline void * _Nonnull passThroughUnsafeMutableRawPointer(void * _Nonnull x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions34passThroughUnsafeMutableRawPointeryS2vF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline void const * _Nonnull passThroughUnsafeRawPointer(void const * _Nonnull x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions27passThroughUnsafeRawPointeryS2VF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: inline void * _Nullable roundTwoPassThroughUnsafeMutableRawPointer(void * _Nullable x) noexcept SWIFT_WARN_UNUSED_RESULT {
|
||||
// CHECK-NEXT: return _impl::$s9Functions42roundTwoPassThroughUnsafeMutableRawPointerySvSgACF(x);
|
||||
// CHECK-NEXT: }
|
||||
|
||||
public func passThroughCBool(_ x: CBool) -> CBool { return x }
|
||||
|
||||
public func passThroughCChar(_ x: CChar) -> CChar { return x }
|
||||
public func passThroughCWideChar(_ x: CWideChar) -> CWideChar { return x }
|
||||
public func passThroughCChar16(_ x: CChar16) -> CChar16 { return x }
|
||||
public func passThroughCChar32(_ x: CChar32) -> CChar32 { return x }
|
||||
|
||||
// Don't test CLong as it's platform specific. See long-lp64 test instead.
|
||||
public func passThroughCSignedChar(_ x: CSignedChar) -> CSignedChar { return x }
|
||||
public func passThroughCShort(_ x: CShort) -> CShort { return x }
|
||||
public func passThroughCInt(_ x: CInt) -> CInt { return x }
|
||||
public func passThroughCLongLong(_ x: CLongLong) -> CLongLong { return x }
|
||||
|
||||
// Don't test CUnsignedLong as it's platform specific. See long-lp64 test instead.
|
||||
public func passThroughCUnsignedSignedChar(_ x: CUnsignedChar) -> CUnsignedChar { return x }
|
||||
public func passThroughCUnsignedShort(_ x: CUnsignedShort) -> CUnsignedShort { return x }
|
||||
public func passThroughCUnsignedInt(_ x: CUnsignedInt) -> CUnsignedInt { return x }
|
||||
public func passThroughCUnsignedLongLong(_ x: CUnsignedLongLong) -> CUnsignedLongLong { return x }
|
||||
|
||||
public func passThrougCFloat(_ x: CFloat) -> CFloat { return x }
|
||||
public func passThroughCDouble(_ x: CDouble) -> CDouble { return x }
|
||||
|
||||
public func passThroughInt8(_ x: Int8) -> Int8 { return x }
|
||||
public func passThroughInt16(_ x: Int16) -> Int16 { return x }
|
||||
public func passThroughInt32(_ x: Int32) -> Int32 { return x }
|
||||
public func passThroughInt64(_ x: Int64) -> Int64 { return x }
|
||||
|
||||
public func passThroughUInt8(_ x: UInt8) -> UInt8 { return x }
|
||||
public func passThroughUInt16(_ x: UInt16) -> UInt16 { return x }
|
||||
public func passThroughUInt32(_ x: UInt32) -> UInt32 { return x }
|
||||
public func passThroughUInt64(_ x: UInt64) -> UInt64 { return x }
|
||||
|
||||
public func passThroughFloat(_ x: Float) -> Float { return x }
|
||||
public func passThroughDouble(_ x: Double) -> Double { return x }
|
||||
public func passThroughFloat32(_ x: Float32) -> Float32 { return x }
|
||||
public func passThroughFloat64(_ x: Float64) -> Float64 { return x }
|
||||
|
||||
public func passThroughInt(_ x: Int) -> Int { return x }
|
||||
public func passThroughUInt(_ x: UInt) -> UInt { return x }
|
||||
public func passThroughBool(_ x: Bool) -> Bool { return x }
|
||||
|
||||
public func passThroughOpaquePointer(_ x: OpaquePointer) -> OpaquePointer { return x }
|
||||
public func passThroughUnsafeRawPointer(_ x: UnsafeRawPointer) -> UnsafeRawPointer { return x }
|
||||
public func passThroughUnsafeMutableRawPointer(_ x: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer { return x }
|
||||
|
||||
public func roundTwoPassThroughUnsafeMutableRawPointer(_ x: UnsafeMutableRawPointer?) -> UnsafeMutableRawPointer? { return x }
|
||||
@@ -0,0 +1,66 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
|
||||
// RUN: %target-swift-frontend %S/swift-primitive-functions-cxx-bridging.swift -typecheck -module-name Functions -clang-header-expose-public-decls -emit-clang-header-path %t/functions.h
|
||||
|
||||
// RUN: %target-interop-build-clangxx -c %s -I %t -o %t/swift-functions-execution.o
|
||||
// RUN: %target-interop-build-swift %S/swift-primitive-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
|
||||
|
||||
// RUN: %target-codesign %t/swift-functions-execution
|
||||
// RUN: %target-run %t/swift-functions-execution
|
||||
|
||||
// REQUIRES: executable_test
|
||||
|
||||
#include <cassert>
|
||||
#include "functions.h"
|
||||
|
||||
#define VERIFY_PASSTHROUGH_VALUE(function, value) assert(function(value) == (value));
|
||||
|
||||
int main() {
|
||||
using namespace Functions;
|
||||
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughCBool, true);
|
||||
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughCChar, 'a');
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughCWideChar, 'a');
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughCChar16, 0xFE1);
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughCChar32, 0x100FE);
|
||||
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughCSignedChar, -1);
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughCShort, -512);
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughCInt, -999999);
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughCLongLong, -999998);
|
||||
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughCUnsignedSignedChar, 255);
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughCUnsignedShort, 0xFFFF);
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughCUnsignedInt, 0xFFFFFFFF);
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughCUnsignedLongLong, 0xFFFFFFFF);
|
||||
|
||||
VERIFY_PASSTHROUGH_VALUE(passThrougCFloat, 1.0f);
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughCDouble, 42.125f);
|
||||
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughInt8, -1);
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughInt16, -512);
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughInt32, -999999);
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughInt64, -999999999999);
|
||||
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughUInt8, 255);
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughUInt16, 0xffff);
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughUInt32, 0xffffffff);
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughUInt64, 0xffffffffffffffff);
|
||||
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughFloat, 1.0f);
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughDouble, 42.125f);
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughFloat32, 1.0f);
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughFloat64, 42.125f);
|
||||
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughInt, -999997);
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughUInt, 0xffffffff);
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughBool, true);
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughBool, false);
|
||||
|
||||
int x = 0;
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughOpaquePointer, &x);
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughUnsafeRawPointer, &x);
|
||||
VERIFY_PASSTHROUGH_VALUE(passThroughUnsafeMutableRawPointer, &x);
|
||||
VERIFY_PASSTHROUGH_VALUE(roundTwoPassThroughUnsafeMutableRawPointer, nullptr);
|
||||
}
|
||||
@@ -583,13 +583,13 @@ extraCheckWarningFlags = (
|
||||
# Don't warn about poison system directories in the Linux system paths.
|
||||
'-Wno-poison-system-directories '
|
||||
# For -fmodules-cache-path, when modules are off.
|
||||
'-Wno-unused-command-line-argument ')
|
||||
'-Wno-unused-command-line-argument '
|
||||
# Don't warn about nullability specifiers in C/C++ code.
|
||||
'-Wno-nullability-extension ')
|
||||
|
||||
# Verifies that a C++ file can be compiled without warnings except for some exceptions.
|
||||
config.substitutions.insert(0, ('%check-c-header-in-clang',
|
||||
'%clang -fsyntax-only -x c-header ' + extraCheckWarningFlags +
|
||||
# Don't warn about nullability specifiers in C code.
|
||||
'-Wno-nullability-extension '
|
||||
# Use standard header/framework search paths.
|
||||
'-F %%clang-importer-sdk-path/frameworks '
|
||||
'-I %%clang-include-dir '
|
||||
|
||||
Reference in New Issue
Block a user