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))"
|
||||
case .boolToGboolean:
|
||||
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:
|
||||
return rawName
|
||||
}
|
||||
|
|
@ -2088,6 +2099,13 @@ private func gvalueGetterBody(swiftType: String, girName: String,
|
|||
resultExpr = hasCopyFunction
|
||||
? "\(swiftType)(retaining: 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 {
|
||||
resultExpr = "g_value_get_\(suffix)(&gvalue)"
|
||||
}
|
||||
|
|
@ -2127,6 +2145,11 @@ private func gvalueSetterBody(swiftType: String, girName: String,
|
|||
: "g_value_set_object(&gvalue, newValue.pointer)"
|
||||
} else if suffix == "boxed" {
|
||||
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 {
|
||||
setCall = "g_value_set_\(suffix)(&gvalue, newValue)"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -594,7 +594,16 @@ extension Mapping {
|
|||
gvalue: GValueOps(typeMacro: "G_TYPE_INT",
|
||||
getterSuffix: "int", setterSuffix: "int"))
|
||||
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"),
|
||||
gvalue: GValueOps(typeMacro: "G_TYPE_INT64",
|
||||
getterSuffix: "int64", setterSuffix: "int64"))
|
||||
|
|
@ -610,7 +619,11 @@ extension Mapping {
|
|||
gvalue: GValueOps(typeMacro: "G_TYPE_UINT",
|
||||
getterSuffix: "uint", setterSuffix: "uint"))
|
||||
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"),
|
||||
gvalue: GValueOps(typeMacro: "G_TYPE_UINT64",
|
||||
getterSuffix: "uint64", setterSuffix: "uint64"))
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ struct TypeMapperTests {
|
|||
PrimitiveCase(type: .int8, swiftType: "Int8", cSwiftType: "Int8", 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: .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")),
|
||||
])
|
||||
func signedIntegers(_ tc: PrimitiveCase) throws {
|
||||
|
|
@ -167,7 +167,7 @@ struct TypeMapperTests {
|
|||
PrimitiveCase(type: .uint8, swiftType: "UInt8", cSwiftType: "UInt8", 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: .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")),
|
||||
])
|
||||
func unsignedIntegers(_ tc: PrimitiveCase) throws {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue