genbindings: merge enums with redundant definitions

This commit is contained in:
mappu 2024-09-16 19:03:45 +12:00
parent 7fdccff799
commit ac2ec49248
5 changed files with 54 additions and 13 deletions

View File

@ -94,9 +94,12 @@ func parseHeader(topLevel []interface{}, addNamePrefix string) (*CppParsedHeader
if err != nil {
panic(fmt.Errorf("processEnum: %w", err)) // A real problem
}
if len(en.Entries) > 0 { // e.g. qmetatype's version of QCborSimpleType (the real one is in qcborcommon)
ret.Enums = append(ret.Enums, en)
}
// n.b. In some cases we may produce multiple "copies" of an enum
// (e.g. qcborcommon and qmetatype both define QCborSimpleType)
// Allow, but use a transform pass to avoid multiple definitions of
// it
ret.Enums = append(ret.Enums, en)
case "VarDecl":
// TODO e.g. qmath.h

View File

@ -400,19 +400,26 @@ import "C"
}
for _, e := range src.Enums {
if e.EnumName == "" {
continue // Removed by transformRedundant AST pass
}
goEnumName := cabiClassName(e.EnumName)
ret.WriteString(`
type ` + goEnumName + ` ` + parseSingleTypeString(e.UnderlyingType).RenderTypeGo() + `
const (
`)
for _, ee := range e.Entries {
ret.WriteString(cabiClassName(goEnumName+"::"+ee.EntryName) + " " + goEnumName + " = " + ee.EntryValue + "\n")
}
if len(e.Entries) > 0 {
ret.WriteString("\n)\n\n")
ret.WriteString("const (\n")
for _, ee := range e.Entries {
ret.WriteString(cabiClassName(goEnumName+"::"+ee.EntryName) + " " + goEnumName + " = " + ee.EntryValue + "\n")
}
ret.WriteString("\n)\n\n")
}
}
for _, c := range src.Classes {

View File

@ -195,10 +195,6 @@ func CheckComplexity(p CppParameter, isReturnType bool) error {
"QXmlStreamAttributes", // e.g. qxmlstream.h
"QVariantMap", // e.g. qcbormap.h
"QVariantHash", // e.g. qcbormap.h
"QCborTag", // e.g. qcborstreamreader.h.TODO Needs support for enums
"QCborSimpleType", // e.g. qcborstreamreader.h TODO Needs support for enums
"QCborKnownTags", // e.g. qcborstreamreader.h TODO Needs support for enums
"QCborNegativeInteger", // e.g. qcborstreamreader.h TODO Needs support for enums
"QtMsgType", // e.g. qdebug.h TODO Needs support for enums
"QTextStreamFunction", // e.g. qdebug.h
"QFactoryInterface", // qfactoryinterface.h

View File

@ -84,6 +84,9 @@ func main() {
}
var processHeaders []*CppParsedHeader
atr := astTransformRedundant{
preserve: make(map[string]*CppEnum),
}
for _, inputHeader := range includeFiles {
@ -149,6 +152,7 @@ func main() {
astTransformChildClasses(parsed) // must be first
astTransformOptional(parsed)
astTransformOverloads(parsed)
atr.Process(parsed)
// Update global state tracker (AFTER astTransformChildClasses)
// Currently, this is only used for inner classes

View File

@ -0,0 +1,31 @@
package main
// astTransformRedundant merges duplicate enum definitions.
type astTransformRedundant struct {
preserve map[string]*CppEnum
}
func (a *astTransformRedundant) Process(parsed *CppParsedHeader) {
for i, e := range parsed.Enums {
prev, ok := a.preserve[e.EnumName]
if !ok {
// It's new
a.preserve[e.EnumName] = &parsed.Enums[i]
continue
}
// It's pre-existing
if prev.UnderlyingType != e.UnderlyingType {
panic("Enum " + e.EnumName + " is defined multiple times with different underlying types")
}
// Merge entries
prev.Entries = append(prev.Entries, e.Entries...)
// Remove from second matched header
// This is difficult to manipulate while preserving pointers, so only
// wipe out the name and use that as a signal later on
parsed.Enums[i].EnumName = ""
}
}