From 189a93fbcae158f85c15f2eabf9fad7d8f397157 Mon Sep 17 00:00:00 2001 From: mappu Date: Thu, 15 Aug 2024 19:49:05 +1200 Subject: [PATCH] genbindings: more integer type handling --- cmd/genbindings/emitcabi.go | 34 +++++++++++++++++++++++---- cmd/genbindings/emitgo.go | 41 +++++++++++++++++++++++++++++++++ cmd/genbindings/intermediate.go | 9 ++++---- 3 files changed, 75 insertions(+), 9 deletions(-) diff --git a/cmd/genbindings/emitcabi.go b/cmd/genbindings/emitcabi.go index 8abf9646..facd97fd 100644 --- a/cmd/genbindings/emitcabi.go +++ b/cmd/genbindings/emitcabi.go @@ -11,14 +11,26 @@ func (p CppParameter) RenderTypeCpp() string { switch p.ParameterType { case "uint": ret = "unsigned int" - case "ushort": - ret = "unsigned short" case "ulong": ret = "unsigned long" - case "qlonglong": + case "qint8": + ret = "int8_t" + case "quint8": + ret = "uint8_t" + case "qint16", "short": + ret = "int16_t" + case "quint16", "ushort", "unsigned short": + ret = "uint16_t" + case "qint32": + ret = "int32_t" + case "quint32": + ret = "uint32_t" + case "qlonglong", "qint64": ret = "int64_t" - case "qulonglong": + case "qulonglong", "quint64": ret = "uint64_t" + case "qfloat16": + ret = "_Float16" // No idea where this typedef comes from, but it exists } if p.Pointer || p.ByRef { @@ -123,11 +135,23 @@ func emitParametersCABI2CppForwarding(params []CppParameter) (preamble string, f } else if p.IntType() { // Use the raw ParameterType to select an explicit integer overload // Don't use RenderTypeCpp() since it canonicalizes some int types for CABI + castSrc := p.ParameterName castType := p.ParameterType if p.Pointer { castType += "*" } - tmp = append(tmp, "static_cast<"+castType+">("+p.ParameterName+")") + if p.ByRef { // e.g. QDataStream::operator>>() overloads + castSrc = "*" + castSrc + castType += "&" // believe it or not, this is legal + + if p.ParameterType == "qint64" || p.ParameterType == "quint64" { + // QDataStream::operator>>() + // CABI has these as int64_t* (long int) which fails a static_cast to qint64& (long long int&) + // Hack a hard C-style cast + castSrc = "(" + castType + ")(" + castSrc + ")" + } + } + tmp = append(tmp, "static_cast<"+castType+">("+castSrc+")") } else if p.ByRef { // We changed RenderTypeCpp() to render this as a pointer diff --git a/cmd/genbindings/emitgo.go b/cmd/genbindings/emitgo.go index 03f9824d..88edef29 100644 --- a/cmd/genbindings/emitgo.go +++ b/cmd/genbindings/emitgo.go @@ -11,6 +11,47 @@ func (p CppParameter) RenderTypeGo() string { if p.Pointer && p.ParameterType == "char" { return "string" } + if !p.Pointer && p.IntType() { + switch p.ParameterType { + case "char", "qint8": + return "byte" + case "unsigned char", "quint8": + return "byte" + case "short", "qint16": + return "int16" + case "ushort", "quint16": + return "uint16" + case "long": + // Windows ILP32 - 32-bits + // Linux LP64 - 64-bits + if C.sizeof_long == 4 { + return "int32" + } else { + return "int64" + } + case "ulong", "unsigned long": + if C.sizeof_long == 4 { + return "uint32" + } else { + return "uint64" + } + case "qint32": + return "int32" + case "quint32": + return "uint32" + case "qlonglong", "qint64": + return "int64" + case "qulonglong", "quint64": + return "uint64" + case "float": + return "float32" + case "double": + return "float64" + } + } + if p.ParameterType == "char" { + return "byte" + } if p.ParameterType == "QString" { return "string" } diff --git a/cmd/genbindings/intermediate.go b/cmd/genbindings/intermediate.go index c9cad00f..5cb7e413 100644 --- a/cmd/genbindings/intermediate.go +++ b/cmd/genbindings/intermediate.go @@ -27,11 +27,12 @@ func (p CppParameter) QListOf() (CppParameter, bool) { func (p CppParameter) IntType() bool { switch p.ParameterType { - case "int", "uint", - "short", "ushort", + case "int", "unsigned int", "uint", + "short", "unsigned short", "ushort", "qint16", "quint16", + "qint8", "quint8", // "char", "uchar", // Don't count char or char* as integer types that need cast assertions - "long", "ulong", - "longlong", "ulonglong", "qlonglong", "qulonglong", "int64_t", "uint64_t", + "long", "unsigned long", "ulong", "qint32", "quint32", + "longlong", "ulonglong", "qlonglong", "qulonglong", "qint64", "quint64", "int64_t", "uint64_t", "long long", "unsigned long long", "double", "float", "qreal": return true default: