diff --git a/cmd/genbindings/clang2il.go b/cmd/genbindings/clang2il.go index 5ab16c83..fc663833 100644 --- a/cmd/genbindings/clang2il.go +++ b/cmd/genbindings/clang2il.go @@ -458,7 +458,7 @@ nextMethod: // Once all processing is complete, pass to exceptions for final decision - if err := AllowMethod(mm); err != nil { + if err := AllowMethod(ret.ClassName, mm); err != nil { if errors.Is(err, ErrTooComplex) { log.Printf("Skipping method %q with complex type", mm.MethodName) continue nextMethod @@ -468,6 +468,8 @@ nextMethod: return CppClass{}, err } + ApplyQuirks(ret.ClassName, &mm) + ret.Methods = append(ret.Methods, mm) default: diff --git a/cmd/genbindings/config-allowlist.go b/cmd/genbindings/config-allowlist.go index 05237e8a..823cca80 100644 --- a/cmd/genbindings/config-allowlist.go +++ b/cmd/genbindings/config-allowlist.go @@ -179,7 +179,7 @@ func AllowSignal(mm CppMethod) bool { } } -func AllowMethod(mm CppMethod) error { +func AllowMethod(className string, mm CppMethod) error { for _, p := range mm.Parameters { if strings.HasSuffix(p.ParameterType, "Private") { @@ -395,3 +395,9 @@ func LinuxWindowsCompatCheck(p CppParameter) bool { } return false } + +func ApplyQuirks(className string, mm *CppMethod) { + if className == "QArrayData" && mm.MethodName == "needsDetach" && mm.IsConst { + mm.BecomesNonConstInVersion = addr("6.7") + } +} diff --git a/cmd/genbindings/emitcabi.go b/cmd/genbindings/emitcabi.go index 36cd999f..3020f423 100644 --- a/cmd/genbindings/emitcabi.go +++ b/cmd/genbindings/emitcabi.go @@ -703,6 +703,23 @@ func emitBindingCpp(src *CppParsedHeader, filename string) (string, error) { m.ReturnType.RenderTypeCabi(), )) + } else if m.BecomesNonConstInVersion != nil { + + nonConstCallTarget := "const_cast<" + cClassName + "*>(self)->" + m.CppCallTarget() + "(" + forwarding + ")" + + ret.WriteString("" + + m.ReturnType.RenderTypeCabi() + " " + cClassName + "_" + m.SafeMethodName() + "(" + emitParametersCabi(m, ifv(m.IsConst, "const ", "")+cClassName+"*") + ") {\n" + + preamble + "\n" + + "// This method was changed from const to non-const in Qt " + *m.BecomesNonConstInVersion + "\n" + + "#if QT_VERSION < QT_VERSION_CHECK(" + strings.Replace(*m.BecomesNonConstInVersion, `.`, `,`, -1) + ",0)\n" + + emitAssignCppToCabi("\treturn ", m.ReturnType, callTarget) + + "#else\n" + + emitAssignCppToCabi("\treturn ", m.ReturnType, nonConstCallTarget) + + "#endif\n" + + "}\n" + + "\n", + ) + } else { ret.WriteString(fmt.Sprintf( diff --git a/cmd/genbindings/intermediate.go b/cmd/genbindings/intermediate.go index ae3802ce..62ddc725 100644 --- a/cmd/genbindings/intermediate.go +++ b/cmd/genbindings/intermediate.go @@ -209,7 +209,10 @@ type CppMethod struct { IsSignal bool IsConst bool HiddenParams []CppParameter // Populated if there is an overload with more parameters - LinuxOnly bool + + // Special quirks + LinuxOnly bool + BecomesNonConstInVersion *string // "6,7" } func (m CppMethod) CppCallTarget() string { diff --git a/cmd/genbindings/util.go b/cmd/genbindings/util.go index 20a7931d..1c6a5989 100644 --- a/cmd/genbindings/util.go +++ b/cmd/genbindings/util.go @@ -33,4 +33,8 @@ func ifv[T any](condition bool, trueval T, falseval T) T { return trueval } return falseval -} \ No newline at end of file +} + +func addr[T any](s T) *T { + return &s +}