genbindings: more accurate enum type handling

This commit is contained in:
mappu 2024-09-18 09:35:53 +12:00
parent 25008355a7
commit b7a488dac0
5 changed files with 24 additions and 31 deletions

View File

@ -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)

View File

@ -73,14 +73,13 @@ 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)
}
}
if p.Pointer {
ret += strings.Repeat("*", p.PointerCount)
@ -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<int>(" + 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<uintptr_t>(" + namePrefix + "_ret);\n"
afterCall += indent + "" + assignExpression + "static_cast<" + p.RenderTypeCabi() + ">(" + namePrefix + "_ret);\n"
}

View File

@ -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 {

View File

@ -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
}

View File

@ -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
}
}