Fix gint64/guint64 marshalling for macOS glib builds
This commit is contained in:
parent
298e5a4b43
commit
5866ed57e9
3 changed files with 40 additions and 4 deletions
|
|
@ -1177,6 +1177,17 @@ private func renderWrapperExpr(for p: ParameterPlan, rawName: String, ownerIsInt
|
||||||
return "String(cString: \(rawName))"
|
return "String(cString: \(rawName))"
|
||||||
case .boolToGboolean:
|
case .boolToGboolean:
|
||||||
return "\(rawName) != 0"
|
return "\(rawName) != 0"
|
||||||
|
case .numericCast:
|
||||||
|
// The raw C parameter is `cSwiftType` (e.g. the literal `gint64`
|
||||||
|
// typedef), which is not always the same nominal type as the
|
||||||
|
// public `swiftType` (`Int`) exposed on the closure. `numericCast`
|
||||||
|
// alone can't infer its target here (this becomes a standalone
|
||||||
|
// `let` binding, with no call-site context to infer from), so
|
||||||
|
// construct the public type directly instead — equivalent to
|
||||||
|
// `numericCast` for the always-non-optional scalar types this
|
||||||
|
// marshalling case covers.
|
||||||
|
let baseType = p.mapping.swiftType.hasSuffix("?") ? String(p.mapping.swiftType.dropLast()) : p.mapping.swiftType
|
||||||
|
return "\(baseType)(\(rawName))"
|
||||||
default:
|
default:
|
||||||
return rawName
|
return rawName
|
||||||
}
|
}
|
||||||
|
|
@ -2088,6 +2099,13 @@ private func gvalueGetterBody(swiftType: String, girName: String,
|
||||||
resultExpr = hasCopyFunction
|
resultExpr = hasCopyFunction
|
||||||
? "\(swiftType)(retaining: g_value_get_boxed(&gvalue))"
|
? "\(swiftType)(retaining: g_value_get_boxed(&gvalue))"
|
||||||
: "\(swiftType)(takingOwnership: g_value_get_boxed(&gvalue))"
|
: "\(swiftType)(takingOwnership: g_value_get_boxed(&gvalue))"
|
||||||
|
} else if suffix == "int64" || suffix == "uint64" {
|
||||||
|
// `g_value_get_int64`/`_uint64` return the literal `gint64`/`guint64`
|
||||||
|
// typedef, which glib defines as `long long` on some platforms and
|
||||||
|
// plain `long` on others (see `TypeMapper.int64Mapping`) — bridge
|
||||||
|
// through `numericCast` so this compiles regardless of which one
|
||||||
|
// the Clang importer resolved it to.
|
||||||
|
resultExpr = "numericCast(g_value_get_\(suffix)(&gvalue))"
|
||||||
} else {
|
} else {
|
||||||
resultExpr = "g_value_get_\(suffix)(&gvalue)"
|
resultExpr = "g_value_get_\(suffix)(&gvalue)"
|
||||||
}
|
}
|
||||||
|
|
@ -2127,6 +2145,11 @@ private func gvalueSetterBody(swiftType: String, girName: String,
|
||||||
: "g_value_set_object(&gvalue, newValue.pointer)"
|
: "g_value_set_object(&gvalue, newValue.pointer)"
|
||||||
} else if suffix == "boxed" {
|
} else if suffix == "boxed" {
|
||||||
setCall = "g_value_set_boxed(&gvalue, newValue.pointer)"
|
setCall = "g_value_set_boxed(&gvalue, newValue.pointer)"
|
||||||
|
} else if suffix == "int64" || suffix == "uint64" {
|
||||||
|
// See the getter's matching branch: `g_value_set_int64`/`_uint64`
|
||||||
|
// take the literal `gint64`/`guint64` typedef, which is not always
|
||||||
|
// the same nominal Swift type as the public `Int`/`UInt` property.
|
||||||
|
setCall = "g_value_set_\(suffix)(&gvalue, numericCast(newValue))"
|
||||||
} else {
|
} else {
|
||||||
setCall = "g_value_set_\(suffix)(&gvalue, newValue)"
|
setCall = "g_value_set_\(suffix)(&gvalue, newValue)"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -594,7 +594,16 @@ extension Mapping {
|
||||||
gvalue: GValueOps(typeMacro: "G_TYPE_INT",
|
gvalue: GValueOps(typeMacro: "G_TYPE_INT",
|
||||||
getterSuffix: "int", setterSuffix: "int"))
|
getterSuffix: "int", setterSuffix: "int"))
|
||||||
static let int64Mapping = Mapping(
|
static let int64Mapping = Mapping(
|
||||||
swiftType: "Int", cSwiftType: "Int", // gint64 → Int on LP64, Int64 on LLP64
|
// `cSwiftType` is the literal glib typedef name, not a guessed Swift
|
||||||
|
// equivalent: glib defines `gint64` unconditionally as `long long`
|
||||||
|
// on some builds (e.g. Homebrew's glib on macOS) and as plain `long`
|
||||||
|
// on others (e.g. glibc-targeting Linux builds), so it imports into
|
||||||
|
// Swift as `Int64` on one and `Int` on the other. Using the raw
|
||||||
|
// typedef name lets the Clang importer resolve the exact pointee
|
||||||
|
// type for out-param locals (`var out0: gint64 = 0; &out0`) on
|
||||||
|
// every platform; `numericCast` still bridges it to the public
|
||||||
|
// `Int` at the Swift boundary.
|
||||||
|
swiftType: "Int", cSwiftType: "gint64",
|
||||||
marshalIn: .numericCast(targetType: "Int"), marshalOut: .numericCast(fromType: "Int"),
|
marshalIn: .numericCast(targetType: "Int"), marshalOut: .numericCast(fromType: "Int"),
|
||||||
gvalue: GValueOps(typeMacro: "G_TYPE_INT64",
|
gvalue: GValueOps(typeMacro: "G_TYPE_INT64",
|
||||||
getterSuffix: "int64", setterSuffix: "int64"))
|
getterSuffix: "int64", setterSuffix: "int64"))
|
||||||
|
|
@ -610,7 +619,11 @@ extension Mapping {
|
||||||
gvalue: GValueOps(typeMacro: "G_TYPE_UINT",
|
gvalue: GValueOps(typeMacro: "G_TYPE_UINT",
|
||||||
getterSuffix: "uint", setterSuffix: "uint"))
|
getterSuffix: "uint", setterSuffix: "uint"))
|
||||||
static let uint64Mapping = Mapping(
|
static let uint64Mapping = Mapping(
|
||||||
swiftType: "UInt", cSwiftType: "UInt", // guint64 → UInt on LP64, UInt64 on LLP64
|
// See `int64Mapping`: `cSwiftType` is the literal `guint64` typedef
|
||||||
|
// name so out-param locals get the exact platform pointee type
|
||||||
|
// regardless of whether glib defines it as `unsigned long long` or
|
||||||
|
// `unsigned long`.
|
||||||
|
swiftType: "UInt", cSwiftType: "guint64",
|
||||||
marshalIn: .numericCast(targetType: "UInt"), marshalOut: .numericCast(fromType: "UInt"),
|
marshalIn: .numericCast(targetType: "UInt"), marshalOut: .numericCast(fromType: "UInt"),
|
||||||
gvalue: GValueOps(typeMacro: "G_TYPE_UINT64",
|
gvalue: GValueOps(typeMacro: "G_TYPE_UINT64",
|
||||||
getterSuffix: "uint64", setterSuffix: "uint64"))
|
getterSuffix: "uint64", setterSuffix: "uint64"))
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ struct TypeMapperTests {
|
||||||
PrimitiveCase(type: .int8, swiftType: "Int8", cSwiftType: "Int8", gvalueTypeMacro: nil, gvalueGetter: nil),
|
PrimitiveCase(type: .int8, swiftType: "Int8", cSwiftType: "Int8", gvalueTypeMacro: nil, gvalueGetter: nil),
|
||||||
PrimitiveCase(type: .int16, swiftType: "Int16", cSwiftType: "Int16", gvalueTypeMacro: nil, gvalueGetter: nil),
|
PrimitiveCase(type: .int16, swiftType: "Int16", cSwiftType: "Int16", gvalueTypeMacro: nil, gvalueGetter: nil),
|
||||||
PrimitiveCase(type: .int32, swiftType: "Int32", cSwiftType: "Int32", gvalueTypeMacro: "G_TYPE_INT", gvalueGetter: "int"),
|
PrimitiveCase(type: .int32, swiftType: "Int32", cSwiftType: "Int32", gvalueTypeMacro: "G_TYPE_INT", gvalueGetter: "int"),
|
||||||
PrimitiveCase(type: .int64, swiftType: "Int", cSwiftType: "Int", gvalueTypeMacro: "G_TYPE_INT64", gvalueGetter: "int64",
|
PrimitiveCase(type: .int64, swiftType: "Int", cSwiftType: "gint64", gvalueTypeMacro: "G_TYPE_INT64", gvalueGetter: "int64",
|
||||||
marshalIn: .numericCast(targetType: "Int"), marshalOut: .numericCast(fromType: "Int")),
|
marshalIn: .numericCast(targetType: "Int"), marshalOut: .numericCast(fromType: "Int")),
|
||||||
])
|
])
|
||||||
func signedIntegers(_ tc: PrimitiveCase) throws {
|
func signedIntegers(_ tc: PrimitiveCase) throws {
|
||||||
|
|
@ -167,7 +167,7 @@ struct TypeMapperTests {
|
||||||
PrimitiveCase(type: .uint8, swiftType: "UInt8", cSwiftType: "UInt8", gvalueTypeMacro: nil, gvalueGetter: nil),
|
PrimitiveCase(type: .uint8, swiftType: "UInt8", cSwiftType: "UInt8", gvalueTypeMacro: nil, gvalueGetter: nil),
|
||||||
PrimitiveCase(type: .uint16, swiftType: "UInt16", cSwiftType: "UInt16", gvalueTypeMacro: nil, gvalueGetter: nil),
|
PrimitiveCase(type: .uint16, swiftType: "UInt16", cSwiftType: "UInt16", gvalueTypeMacro: nil, gvalueGetter: nil),
|
||||||
PrimitiveCase(type: .uint32, swiftType: "UInt32", cSwiftType: "UInt32", gvalueTypeMacro: "G_TYPE_UINT", gvalueGetter: "uint"),
|
PrimitiveCase(type: .uint32, swiftType: "UInt32", cSwiftType: "UInt32", gvalueTypeMacro: "G_TYPE_UINT", gvalueGetter: "uint"),
|
||||||
PrimitiveCase(type: .uint64, swiftType: "UInt", cSwiftType: "UInt", gvalueTypeMacro: "G_TYPE_UINT64", gvalueGetter: "uint64",
|
PrimitiveCase(type: .uint64, swiftType: "UInt", cSwiftType: "guint64", gvalueTypeMacro: "G_TYPE_UINT64", gvalueGetter: "uint64",
|
||||||
marshalIn: .numericCast(targetType: "UInt"), marshalOut: .numericCast(fromType: "UInt")),
|
marshalIn: .numericCast(targetType: "UInt"), marshalOut: .numericCast(fromType: "UInt")),
|
||||||
])
|
])
|
||||||
func unsignedIntegers(_ tc: PrimitiveCase) throws {
|
func unsignedIntegers(_ tc: PrimitiveCase) throws {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue