[cxx-interop] Mark all CxxStdlib APIs as @inlinable

This is a requirement for being able to use the CxxStdlib overlay with a C++ standard library which is not the platform default, specifically libc++ on Linux.

The module would get rebuilt from its textual interface (`CxxStdlib.swiftinterface`) by the compiler whenever a custom C++ stdlib is used. Since the mangled names of C++ stdlib symbols differ across implementations (libc++ vs libstdc++), a Swift program that uses these overlay functions would fail to link, unless the definitions of these functions are available.

rdar://138838506
This commit is contained in:
Egor Zhdan
2024-11-20 20:26:02 +00:00
parent ec8558942c
commit 269fc941de
2 changed files with 42 additions and 0 deletions

View File

@@ -14,6 +14,7 @@ import CxxStdlibShim
extension std.chrono.seconds { extension std.chrono.seconds {
@available(SwiftStdlib 5.7, *) @available(SwiftStdlib 5.7, *)
@inlinable
public init(_ duration: Duration) { public init(_ duration: Duration) {
let (seconds, _) = duration.components let (seconds, _) = duration.components
self = __swift_interopMakeChronoSeconds(seconds) self = __swift_interopMakeChronoSeconds(seconds)
@@ -22,6 +23,7 @@ extension std.chrono.seconds {
extension std.chrono.milliseconds { extension std.chrono.milliseconds {
@available(SwiftStdlib 5.7, *) @available(SwiftStdlib 5.7, *)
@inlinable
public init(_ duration: Duration) { public init(_ duration: Duration) {
let (seconds, attoseconds) = duration.components let (seconds, attoseconds) = duration.components
self = __swift_interopMakeChronoMilliseconds( self = __swift_interopMakeChronoMilliseconds(
@@ -32,6 +34,7 @@ extension std.chrono.milliseconds {
extension std.chrono.microseconds { extension std.chrono.microseconds {
@available(SwiftStdlib 5.7, *) @available(SwiftStdlib 5.7, *)
@inlinable
public init(_ duration: Duration) { public init(_ duration: Duration) {
let (seconds, attoseconds) = duration.components let (seconds, attoseconds) = duration.components
self = __swift_interopMakeChronoMicroseconds( self = __swift_interopMakeChronoMicroseconds(
@@ -42,6 +45,7 @@ extension std.chrono.microseconds {
extension std.chrono.nanoseconds { extension std.chrono.nanoseconds {
@available(SwiftStdlib 5.7, *) @available(SwiftStdlib 5.7, *)
@inlinable
public init(_ duration: Duration) { public init(_ duration: Duration) {
let (seconds, attoseconds) = duration.components let (seconds, attoseconds) = duration.components
self = __swift_interopMakeChronoNanoseconds( self = __swift_interopMakeChronoNanoseconds(
@@ -52,18 +56,22 @@ extension std.chrono.nanoseconds {
@available(SwiftStdlib 5.7, *) @available(SwiftStdlib 5.7, *)
extension Duration { extension Duration {
@inlinable
public init(_ seconds: std.chrono.seconds) { public init(_ seconds: std.chrono.seconds) {
self = Duration.seconds(seconds.count()) self = Duration.seconds(seconds.count())
} }
@inlinable
public init(_ milliseconds: std.chrono.milliseconds) { public init(_ milliseconds: std.chrono.milliseconds) {
self = Duration.milliseconds(milliseconds.count()) self = Duration.milliseconds(milliseconds.count())
} }
@inlinable
public init(_ microseconds: std.chrono.microseconds) { public init(_ microseconds: std.chrono.microseconds) {
self = Duration.microseconds(microseconds.count()) self = Duration.microseconds(microseconds.count())
} }
@inlinable
public init(_ nanoseconds: std.chrono.nanoseconds) { public init(_ nanoseconds: std.chrono.nanoseconds) {
self = Duration.nanoseconds(nanoseconds.count()) self = Duration.nanoseconds(nanoseconds.count())
} }

View File

@@ -19,6 +19,7 @@ extension std.string {
/// ///
/// - Complexity: O(*n*), where *n* is the number of UTF-8 code units in the /// - Complexity: O(*n*), where *n* is the number of UTF-8 code units in the
/// Swift string. /// Swift string.
@inlinable
public init(_ string: String) { public init(_ string: String) {
self = string.withCString(encodedAs: UTF8.self) { buffer in self = string.withCString(encodedAs: UTF8.self) { buffer in
#if os(Windows) #if os(Windows)
@@ -32,6 +33,7 @@ extension std.string {
} }
} }
@inlinable
public init(_ string: UnsafePointer<CChar>?) { public init(_ string: UnsafePointer<CChar>?) {
if let str = string { if let str = string {
#if os(Windows) #if os(Windows)
@@ -54,6 +56,7 @@ extension std.u16string {
/// ///
/// - Complexity: O(*n*), where *n* is the number of UTF-16 code units in the /// - Complexity: O(*n*), where *n* is the number of UTF-16 code units in the
/// Swift string. /// Swift string.
@inlinable
public init(_ string: String) { public init(_ string: String) {
self.init() self.init()
for char in string.utf16 { for char in string.utf16 {
@@ -68,6 +71,7 @@ extension std.u32string {
/// ///
/// - Complexity: O(*n*), where *n* is the number of UTF-32 code units in the /// - Complexity: O(*n*), where *n* is the number of UTF-32 code units in the
/// Swift string. /// Swift string.
@inlinable
public init(_ string: String) { public init(_ string: String) {
self.init() self.init()
for char in string.unicodeScalars { for char in string.unicodeScalars {
@@ -79,18 +83,21 @@ extension std.u32string {
// MARK: Initializing C++ string from a Swift String literal // MARK: Initializing C++ string from a Swift String literal
extension std.string: ExpressibleByStringLiteral { extension std.string: ExpressibleByStringLiteral {
@inlinable
public init(stringLiteral value: String) { public init(stringLiteral value: String) {
self.init(value) self.init(value)
} }
} }
extension std.u16string: ExpressibleByStringLiteral { extension std.u16string: ExpressibleByStringLiteral {
@inlinable
public init(stringLiteral value: String) { public init(stringLiteral value: String) {
self.init(value) self.init(value)
} }
} }
extension std.u32string: ExpressibleByStringLiteral { extension std.u32string: ExpressibleByStringLiteral {
@inlinable
public init(stringLiteral value: String) { public init(stringLiteral value: String) {
self.init(value) self.init(value)
} }
@@ -99,14 +106,17 @@ extension std.u32string: ExpressibleByStringLiteral {
// MARK: Concatenating and comparing C++ strings // MARK: Concatenating and comparing C++ strings
extension std.string: Equatable, Comparable { extension std.string: Equatable, Comparable {
@inlinable
public static func ==(lhs: std.string, rhs: std.string) -> Bool { public static func ==(lhs: std.string, rhs: std.string) -> Bool {
return lhs.compare(rhs) == 0 return lhs.compare(rhs) == 0
} }
@inlinable
public static func <(lhs: std.string, rhs: std.string) -> Bool { public static func <(lhs: std.string, rhs: std.string) -> Bool {
return lhs.compare(rhs) < 0 return lhs.compare(rhs) < 0
} }
@inlinable
public static func +=(lhs: inout std.string, rhs: std.string) { public static func +=(lhs: inout std.string, rhs: std.string) {
lhs.append(rhs) lhs.append(rhs)
} }
@@ -116,6 +126,7 @@ extension std.string: Equatable, Comparable {
__appendUnsafe(other) // ignore the returned pointer __appendUnsafe(other) // ignore the returned pointer
} }
@inlinable
public static func +(lhs: std.string, rhs: std.string) -> std.string { public static func +(lhs: std.string, rhs: std.string) -> std.string {
var copy = lhs var copy = lhs
copy += rhs copy += rhs
@@ -124,14 +135,17 @@ extension std.string: Equatable, Comparable {
} }
extension std.u16string: Equatable, Comparable { extension std.u16string: Equatable, Comparable {
@inlinable
public static func ==(lhs: std.u16string, rhs: std.u16string) -> Bool { public static func ==(lhs: std.u16string, rhs: std.u16string) -> Bool {
return lhs.compare(rhs) == 0 return lhs.compare(rhs) == 0
} }
@inlinable
public static func <(lhs: std.u16string, rhs: std.u16string) -> Bool { public static func <(lhs: std.u16string, rhs: std.u16string) -> Bool {
return lhs.compare(rhs) < 0 return lhs.compare(rhs) < 0
} }
@inlinable
public static func +=(lhs: inout std.u16string, rhs: std.u16string) { public static func +=(lhs: inout std.u16string, rhs: std.u16string) {
lhs.append(rhs) lhs.append(rhs)
} }
@@ -141,6 +155,7 @@ extension std.u16string: Equatable, Comparable {
__appendUnsafe(other) // ignore the returned pointer __appendUnsafe(other) // ignore the returned pointer
} }
@inlinable
public static func +(lhs: std.u16string, rhs: std.u16string) -> std.u16string { public static func +(lhs: std.u16string, rhs: std.u16string) -> std.u16string {
var copy = lhs var copy = lhs
copy += rhs copy += rhs
@@ -149,14 +164,17 @@ extension std.u16string: Equatable, Comparable {
} }
extension std.u32string: Equatable, Comparable { extension std.u32string: Equatable, Comparable {
@inlinable
public static func ==(lhs: std.u32string, rhs: std.u32string) -> Bool { public static func ==(lhs: std.u32string, rhs: std.u32string) -> Bool {
return lhs.compare(rhs) == 0 return lhs.compare(rhs) == 0
} }
@inlinable
public static func <(lhs: std.u32string, rhs: std.u32string) -> Bool { public static func <(lhs: std.u32string, rhs: std.u32string) -> Bool {
return lhs.compare(rhs) < 0 return lhs.compare(rhs) < 0
} }
@inlinable
public static func +=(lhs: inout std.u32string, rhs: std.u32string) { public static func +=(lhs: inout std.u32string, rhs: std.u32string) {
lhs.append(rhs) lhs.append(rhs)
} }
@@ -166,6 +184,7 @@ extension std.u32string: Equatable, Comparable {
__appendUnsafe(other) // ignore the returned pointer __appendUnsafe(other) // ignore the returned pointer
} }
@inlinable
public static func +(lhs: std.u32string, rhs: std.u32string) -> std.u32string { public static func +(lhs: std.u32string, rhs: std.u32string) -> std.u32string {
var copy = lhs var copy = lhs
copy += rhs copy += rhs
@@ -176,6 +195,7 @@ extension std.u32string: Equatable, Comparable {
// MARK: Hashing C++ strings // MARK: Hashing C++ strings
extension std.string: Hashable { extension std.string: Hashable {
@inlinable
public func hash(into hasher: inout Hasher) { public func hash(into hasher: inout Hasher) {
// Call std::hash<std::string>::operator() // Call std::hash<std::string>::operator()
let cxxHash = __swift_interopHashOfString().callAsFunction(self) let cxxHash = __swift_interopHashOfString().callAsFunction(self)
@@ -184,6 +204,7 @@ extension std.string: Hashable {
} }
extension std.u16string: Hashable { extension std.u16string: Hashable {
@inlinable
public func hash(into hasher: inout Hasher) { public func hash(into hasher: inout Hasher) {
// Call std::hash<std::u16string>::operator() // Call std::hash<std::u16string>::operator()
let cxxHash = __swift_interopHashOfU16String().callAsFunction(self) let cxxHash = __swift_interopHashOfU16String().callAsFunction(self)
@@ -192,6 +213,7 @@ extension std.u16string: Hashable {
} }
extension std.u32string: Hashable { extension std.u32string: Hashable {
@inlinable
public func hash(into hasher: inout Hasher) { public func hash(into hasher: inout Hasher) {
// Call std::hash<std::u32string>::operator() // Call std::hash<std::u32string>::operator()
let cxxHash = __swift_interopHashOfU32String().callAsFunction(self) let cxxHash = __swift_interopHashOfU32String().callAsFunction(self)
@@ -202,36 +224,42 @@ extension std.u32string: Hashable {
// MARK: Getting a Swift description of a C++ string // MARK: Getting a Swift description of a C++ string
extension std.string: CustomDebugStringConvertible { extension std.string: CustomDebugStringConvertible {
@inlinable
public var debugDescription: String { public var debugDescription: String {
return "std.string(\(String(self)))" return "std.string(\(String(self)))"
} }
} }
extension std.u16string: CustomDebugStringConvertible { extension std.u16string: CustomDebugStringConvertible {
@inlinable
public var debugDescription: String { public var debugDescription: String {
return "std.u16string(\(String(self)))" return "std.u16string(\(String(self)))"
} }
} }
extension std.u32string: CustomDebugStringConvertible { extension std.u32string: CustomDebugStringConvertible {
@inlinable
public var debugDescription: String { public var debugDescription: String {
return "std.u32string(\(String(self)))" return "std.u32string(\(String(self)))"
} }
} }
extension std.string: CustomStringConvertible { extension std.string: CustomStringConvertible {
@inlinable
public var description: String { public var description: String {
return String(self) return String(self)
} }
} }
extension std.u16string: CustomStringConvertible { extension std.u16string: CustomStringConvertible {
@inlinable
public var description: String { public var description: String {
return String(self) return String(self)
} }
} }
extension std.u32string: CustomStringConvertible { extension std.u32string: CustomStringConvertible {
@inlinable
public var description: String { public var description: String {
return String(self) return String(self)
} }
@@ -247,6 +275,7 @@ extension String {
/// (`"\u{FFFD}"`). /// (`"\u{FFFD}"`).
/// ///
/// - Complexity: O(*n*), where *n* is the number of bytes in the C++ string. /// - Complexity: O(*n*), where *n* is the number of bytes in the C++ string.
@inlinable
public init(_ cxxString: std.string) { public init(_ cxxString: std.string) {
let buffer = UnsafeBufferPointer<CChar>( let buffer = UnsafeBufferPointer<CChar>(
start: cxxString.__c_strUnsafe(), start: cxxString.__c_strUnsafe(),
@@ -265,6 +294,7 @@ extension String {
/// ///
/// - Complexity: O(*n*), where *n* is the number of bytes in the C++ UTF-16 /// - Complexity: O(*n*), where *n* is the number of bytes in the C++ UTF-16
/// string. /// string.
@inlinable
public init(_ cxxU16String: std.u16string) { public init(_ cxxU16String: std.u16string) {
let buffer = UnsafeBufferPointer<UInt16>( let buffer = UnsafeBufferPointer<UInt16>(
start: cxxU16String.__dataUnsafe(), start: cxxU16String.__dataUnsafe(),
@@ -281,6 +311,7 @@ extension String {
/// ///
/// - Complexity: O(*n*), where *n* is the number of bytes in the C++ UTF-32 /// - Complexity: O(*n*), where *n* is the number of bytes in the C++ UTF-32
/// string. /// string.
@inlinable
public init(_ cxxU32String: std.u32string) { public init(_ cxxU32String: std.u32string) {
let buffer = UnsafeBufferPointer<Unicode.Scalar>( let buffer = UnsafeBufferPointer<Unicode.Scalar>(
start: cxxU32String.__dataUnsafe(), start: cxxU32String.__dataUnsafe(),
@@ -303,6 +334,7 @@ extension String {
/// ///
/// - Complexity: O(*n*), where *n* is the number of bytes in the C++ string /// - Complexity: O(*n*), where *n* is the number of bytes in the C++ string
/// view. /// view.
@inlinable
public init(_ cxxStringView: std.string_view) { public init(_ cxxStringView: std.string_view) {
let buffer = UnsafeBufferPointer<CChar>( let buffer = UnsafeBufferPointer<CChar>(
start: cxxStringView.__dataUnsafe(), start: cxxStringView.__dataUnsafe(),
@@ -322,6 +354,7 @@ extension String {
/// ///
/// - Complexity: O(*n*), where *n* is the number of bytes in the C++ UTF-16 /// - Complexity: O(*n*), where *n* is the number of bytes in the C++ UTF-16
/// string view. /// string view.
@inlinable
public init(_ cxxU16StringView: std.u16string_view) { public init(_ cxxU16StringView: std.u16string_view) {
let buffer = UnsafeBufferPointer<UInt16>( let buffer = UnsafeBufferPointer<UInt16>(
start: cxxU16StringView.__dataUnsafe(), start: cxxU16StringView.__dataUnsafe(),
@@ -339,6 +372,7 @@ extension String {
/// ///
/// - Complexity: O(*n*), where *n* is the number of bytes in the C++ UTF-32 /// - Complexity: O(*n*), where *n* is the number of bytes in the C++ UTF-32
/// string view. /// string view.
@inlinable
public init(_ cxxU32StringView: std.u32string_view) { public init(_ cxxU32StringView: std.u32string_view) {
let buffer = UnsafeBufferPointer<Unicode.Scalar>( let buffer = UnsafeBufferPointer<Unicode.Scalar>(
start: cxxU32StringView.__dataUnsafe(), start: cxxU32StringView.__dataUnsafe(),