mirror of
https://github.com/mappu/miqt.git
synced 2024-12-22 08:58:37 +00:00
genbindings: use knownClassNames tracker to distinguish A::B names
This commit is contained in:
parent
02370ce0ea
commit
85cf3b84d8
@ -46,7 +46,13 @@ func (p CppParameter) RenderTypeCabi() string {
|
||||
}
|
||||
|
||||
if strings.Contains(p.ParameterType, `::`) {
|
||||
ret = "int"
|
||||
if _, ok := KnownClassnames[p.ParameterType]; ok {
|
||||
// Inner class
|
||||
ret = cabiClassName(p.ParameterType)
|
||||
} else {
|
||||
// Enum
|
||||
ret = "uintptr_t"
|
||||
}
|
||||
}
|
||||
|
||||
if p.Pointer || p.ByRef {
|
||||
@ -64,11 +70,11 @@ func emitReturnTypeCabi(p CppParameter) string {
|
||||
return "void" // Will be handled separately
|
||||
|
||||
} else if (p.Pointer || p.ByRef) && p.QtClassType() {
|
||||
return p.ParameterType + "*" // CABI type
|
||||
return cabiClassName(p.ParameterType) + "*" // CABI type
|
||||
|
||||
} else if p.QtClassType() && !p.Pointer {
|
||||
// Even if C++ returns by value, CABI is returning a heap copy (new'd, not malloc'd)
|
||||
return p.ParameterType + "*" // CABI type
|
||||
return cabiClassName(p.ParameterType) + "*" // CABI type
|
||||
// return "void" // Handled separately with an _out pointer
|
||||
|
||||
} else {
|
||||
@ -77,10 +83,8 @@ func emitReturnTypeCabi(p CppParameter) string {
|
||||
}
|
||||
|
||||
func (p CppParameter) RenderTypeQtCpp() string {
|
||||
cppType := p.ParameterType
|
||||
if len(p.TypeAlias) > 0 {
|
||||
cppType = p.TypeAlias // replace
|
||||
}
|
||||
cppType := p.UnderlyingType()
|
||||
|
||||
if p.Const {
|
||||
cppType = "const " + cppType
|
||||
}
|
||||
@ -147,13 +151,13 @@ func emitParametersCabi(m CppMethod, selfType string) string {
|
||||
} else if (p.ByRef || p.Pointer) && p.QtClassType() {
|
||||
// Pointer to Qt type
|
||||
// Replace with taking our PQ typedef by value
|
||||
tmp = append(tmp, p.ParameterType+"* "+p.ParameterName)
|
||||
tmp = append(tmp, cabiClassName(p.ParameterType)+"* "+p.ParameterName)
|
||||
|
||||
} else if p.QtClassType() {
|
||||
// Qt type passed by value
|
||||
// The CABI will unconditionally take these by pointer and dereference them
|
||||
// when passing to C++
|
||||
tmp = append(tmp, p.ParameterType+"* "+p.ParameterName)
|
||||
tmp = append(tmp, cabiClassName(p.ParameterType)+"* "+p.ParameterName)
|
||||
|
||||
} else {
|
||||
// RenderTypeCabi renders both pointer+reference as pointers
|
||||
@ -235,13 +239,9 @@ func emitParametersCABI2CppForwarding(params []CppParameter) (preamble string, f
|
||||
// Use the raw ParameterType to select an explicit integer overload
|
||||
// Don't use RenderTypeCabi() since it canonicalizes some int types for CABI
|
||||
castSrc := p.ParameterName
|
||||
castType := p.ParameterType
|
||||
if p.Pointer {
|
||||
castType += "*"
|
||||
}
|
||||
castType := p.RenderTypeQtCpp()
|
||||
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" || p.ParameterType == "qlonglong" || p.ParameterType == "qulonglong" {
|
||||
|
@ -88,7 +88,13 @@ func (p CppParameter) RenderTypeGo() string {
|
||||
default:
|
||||
|
||||
if strings.Contains(p.ParameterType, `::`) {
|
||||
ret += "int"
|
||||
if _, ok := KnownClassnames[p.ParameterType]; ok {
|
||||
// Inner class
|
||||
ret += cabiClassName(p.ParameterType)
|
||||
} else {
|
||||
// Enum
|
||||
ret += "uintptr"
|
||||
}
|
||||
} else {
|
||||
// Do not transform this type
|
||||
ret += p.ParameterType
|
||||
@ -314,7 +320,7 @@ import "C"
|
||||
localInit := "h: h"
|
||||
for _, base := range c.Inherits {
|
||||
gfs.imports["unsafe"] = struct{}{}
|
||||
localInit += ", " + base + ": new" + base + "_U(unsafe.Pointer(h))"
|
||||
localInit += ", " + base + ": new" + cabiClassName(base) + "_U(unsafe.Pointer(h))"
|
||||
}
|
||||
|
||||
ret.WriteString(`
|
||||
@ -419,9 +425,9 @@ import "C"
|
||||
if t.QtClassType() {
|
||||
if !t.Pointer {
|
||||
// new, but then dereference it
|
||||
afterword += "ret[i] = *new" + t.ParameterType + "(_outCast[i])\n"
|
||||
afterword += "ret[i] = *new" + cabiClassName(t.ParameterType) + "(_outCast[i])\n"
|
||||
} else {
|
||||
afterword += "ret[i] = new" + t.ParameterType + "(_outCast[i])\n"
|
||||
afterword += "ret[i] = new" + cabiClassName(t.ParameterType) + "(_outCast[i])\n"
|
||||
}
|
||||
} else { // plain int type
|
||||
afterword += "ret[i] = (" + t.RenderTypeGo() + ")(_outCast[i])\n"
|
||||
@ -437,7 +443,7 @@ import "C"
|
||||
|
||||
if m.ReturnType.Pointer || m.ReturnType.ByRef {
|
||||
gfs.imports["unsafe"] = struct{}{}
|
||||
afterword = "return new" + m.ReturnType.ParameterType + "_U(unsafe.Pointer(ret))"
|
||||
afterword = "return new" + cabiClassName(m.ReturnType.ParameterType) + "_U(unsafe.Pointer(ret))"
|
||||
|
||||
} else {
|
||||
// This is return by value, but CABI has new'd it into a
|
||||
@ -449,8 +455,8 @@ import "C"
|
||||
|
||||
gfs.imports["runtime"] = struct{}{}
|
||||
afterword = "// Qt uses pass-by-value semantics for this type. Mimic with finalizer\n"
|
||||
afterword += "ret1 := new" + m.ReturnType.ParameterType + "(ret)\n"
|
||||
afterword += "runtime.SetFinalizer(ret1, func(ret2 *" + m.ReturnType.ParameterType + ") {\n"
|
||||
afterword += "ret1 := new" + cabiClassName(m.ReturnType.ParameterType) + "(ret)\n"
|
||||
afterword += "runtime.SetFinalizer(ret1, func(ret2 *" + cabiClassName(m.ReturnType.ParameterType) + ") {\n"
|
||||
afterword += "ret2.Delete()\n"
|
||||
afterword += "runtime.KeepAlive(ret2.h)\n"
|
||||
afterword += "})\n"
|
||||
|
@ -5,6 +5,14 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
KnownClassnames map[string]struct{} // Entries of the form QFoo::Bar if it is an inner class
|
||||
)
|
||||
|
||||
func init() {
|
||||
KnownClassnames = make(map[string]struct{})
|
||||
}
|
||||
|
||||
type CppParameter struct {
|
||||
ParameterName string
|
||||
ParameterType string
|
||||
@ -15,8 +23,30 @@ type CppParameter struct {
|
||||
Optional bool
|
||||
}
|
||||
|
||||
func (p *CppParameter) UnderlyingType() string {
|
||||
if p.TypeAlias != "" {
|
||||
return p.TypeAlias
|
||||
}
|
||||
|
||||
return p.ParameterType
|
||||
}
|
||||
|
||||
func (p CppParameter) QtClassType() bool {
|
||||
return (p.ParameterType[0] == 'Q') && p.ParameterType != "QRgb" && !strings.Contains(p.ParameterType, `::`)
|
||||
if p.ParameterType[0] != 'Q' {
|
||||
return false
|
||||
}
|
||||
|
||||
if strings.Contains(p.ParameterType, `::`) {
|
||||
// Maybe if it's an inner class
|
||||
if _, ok := KnownClassnames[p.ParameterType]; ok {
|
||||
return true
|
||||
}
|
||||
// Int type
|
||||
return false
|
||||
}
|
||||
|
||||
// Passed all conditions
|
||||
return true
|
||||
}
|
||||
|
||||
func (p CppParameter) QListOf() (CppParameter, bool) {
|
||||
|
@ -136,6 +136,11 @@ func main() {
|
||||
astTransformOptional(parsed)
|
||||
astTransformOverloads(parsed)
|
||||
|
||||
// Update global state tracker (AFTER astTransformChildClasses)
|
||||
// Currently, this is only used for inner classes
|
||||
for _, c := range parsed.Classes {
|
||||
KnownClassnames[c.ClassName] = struct{}{}
|
||||
}
|
||||
processHeaders = append(processHeaders, parsed)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user