From b7a488dac0609cf5c9759264bd2ddf0369b1c062 Mon Sep 17 00:00:00 2001 From: mappu Date: Wed, 18 Sep 2024 09:35:53 +1200 Subject: [PATCH] genbindings: more accurate enum type handling --- cmd/genbindings/clang2il.go | 6 +++--- cmd/genbindings/emitcabi.go | 20 ++++++++++++-------- cmd/genbindings/emitgo.go | 4 +--- cmd/genbindings/intermediate.go | 19 ++----------------- cmd/genbindings/transformtypedefs.go | 6 ++++++ 5 files changed, 24 insertions(+), 31 deletions(-) diff --git a/cmd/genbindings/clang2il.go b/cmd/genbindings/clang2il.go index 11cf71f9..0ed54b08 100644 --- a/cmd/genbindings/clang2il.go +++ b/cmd/genbindings/clang2il.go @@ -485,10 +485,10 @@ func processEnum(node map[string]interface{}, addNamePrefix string) (CppEnum, er var ret CppEnum // Underlying type - ret.UnderlyingType = "int" + ret.UnderlyingType = parseSingleTypeString("int") if nodefut, ok := node["fixedUnderlyingType"].(map[string]interface{}); ok { if nodequal, ok := nodefut["qualType"].(string); ok { - ret.UnderlyingType = nodequal + ret.UnderlyingType = parseSingleTypeString(nodequal) } } @@ -577,7 +577,7 @@ func processEnum(node map[string]interface{}, addNamePrefix string) (CppEnum, er var err error if cee.EntryValue == "true" || cee.EntryValue == "false" { - ret.UnderlyingType = "bool" + ret.UnderlyingType = parseSingleTypeString("bool") } else { lastImplicitValue, err = strconv.ParseInt(cee.EntryValue, 10, 64) diff --git a/cmd/genbindings/emitcabi.go b/cmd/genbindings/emitcabi.go index cb5a402e..c99c22d9 100644 --- a/cmd/genbindings/emitcabi.go +++ b/cmd/genbindings/emitcabi.go @@ -73,13 +73,12 @@ func (p CppParameter) RenderTypeCabi() string { if p.IsFlagType() { ret = "int" + } else if e, ok := KnownEnums[p.ParameterType]; ok { + ret = e.UnderlyingType.RenderTypeCabi() + } else if strings.Contains(p.ParameterType, `::`) { - if p.IsEnum() { - ret = "uintptr_t" - } else { - // Inner class - ret = cabiClassName(p.ParameterType) - } + // Inner class + ret = cabiClassName(p.ParameterType) } if p.Pointer { @@ -208,6 +207,11 @@ func emitCABI2CppForwarding(p CppParameter, indent string) (preamble string, for preamble += indent + "}\n" return preamble, nameprefix + "_QList" + } else if p.IsKnownEnum() { + // The enums are projected in CABI as their underlying int types. + // Cast to the Qt enum type so that we get the correct overload + return preamble, "static_cast<" + p.RenderTypeQtCpp() + ">(" + p.ParameterName + ")" + } else if p.IntType() { // Use the raw ParameterType to select an explicit integer overload // Don't use RenderTypeCabi() since it canonicalizes some int types for CABI @@ -370,10 +374,10 @@ func emitAssignCppToCabi(assignExpression string, p CppParameter, rvalue string) shouldReturn = p.RenderTypeQtCpp() + " " + namePrefix + "_ret = " afterCall += indent + "" + assignExpression + "static_cast(" + namePrefix + "_ret);\n" - } else if p.IsEnum() { + } else if p.IsKnownEnum() { // Needs an explicit uintptr cast shouldReturn = p.RenderTypeQtCpp() + " " + namePrefix + "_ret = " - afterCall += indent + "" + assignExpression + "static_cast(" + namePrefix + "_ret);\n" + afterCall += indent + "" + assignExpression + "static_cast<" + p.RenderTypeCabi() + ">(" + namePrefix + "_ret);\n" } diff --git a/cmd/genbindings/emitgo.go b/cmd/genbindings/emitgo.go index 58f7f0ba..428d27e9 100644 --- a/cmd/genbindings/emitgo.go +++ b/cmd/genbindings/emitgo.go @@ -93,8 +93,6 @@ func (p CppParameter) RenderTypeGo() string { if p.IsKnownEnum() { ret += cabiClassName(p.ParameterType) - } else if p.IsEnum() { - ret += "uintptr" } else { // Inner class ret += cabiClassName(p.ParameterType) @@ -411,7 +409,7 @@ import "C" goEnumName := cabiClassName(e.EnumName) ret.WriteString(` - type ` + goEnumName + ` ` + parseSingleTypeString(e.UnderlyingType).RenderTypeGo() + ` + type ` + goEnumName + ` ` + e.UnderlyingType.RenderTypeGo() + ` `) if len(e.Entries) > 0 { diff --git a/cmd/genbindings/intermediate.go b/cmd/genbindings/intermediate.go index 5413f7e7..e22e2358 100644 --- a/cmd/genbindings/intermediate.go +++ b/cmd/genbindings/intermediate.go @@ -116,21 +116,6 @@ func (p CppParameter) IsKnownEnum() bool { return ok } -func (p CppParameter) IsEnum() bool { - if strings.Contains(p.ParameterType, `::`) { - if _, ok := KnownClassnames[p.ParameterType]; ok { - // It's an inner class - return false - } else { - // Enum - return true - } - } - - // Top-level enums aren't supported yet - return false -} - func (p CppParameter) QListOf() (CppParameter, bool) { if strings.HasPrefix(p.ParameterType, "QList<") && strings.HasSuffix(p.ParameterType, `>`) { ret := parseSingleTypeString(p.ParameterType[6 : len(p.ParameterType)-1]) @@ -168,7 +153,7 @@ func (p CppParameter) QSetOf() (CppParameter, bool) { func (p CppParameter) IntType() bool { - if p.IsEnum() { + if p.IsKnownEnum() { return true } @@ -326,7 +311,7 @@ type CppEnumEntry struct { type CppEnum struct { EnumName string - UnderlyingType string + UnderlyingType CppParameter Entries []CppEnumEntry } diff --git a/cmd/genbindings/transformtypedefs.go b/cmd/genbindings/transformtypedefs.go index b0cd786e..4d86b2d5 100644 --- a/cmd/genbindings/transformtypedefs.go +++ b/cmd/genbindings/transformtypedefs.go @@ -66,4 +66,10 @@ func astTransformTypedefs(parsed *CppParsedHeader) { } parsed.Classes[i] = c } + + // Enum underlying types + for i, e := range parsed.Enums { + e.UnderlyingType = applyTypedefs(e.UnderlyingType) + parsed.Enums[i] = e + } }