mirror of
https://github.com/mappu/miqt.git
synced 2025-04-04 20:50:22 +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, `::`) {
|
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 {
|
if p.Pointer || p.ByRef {
|
||||||
@ -64,11 +70,11 @@ func emitReturnTypeCabi(p CppParameter) string {
|
|||||||
return "void" // Will be handled separately
|
return "void" // Will be handled separately
|
||||||
|
|
||||||
} else if (p.Pointer || p.ByRef) && p.QtClassType() {
|
} 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 {
|
} else if p.QtClassType() && !p.Pointer {
|
||||||
// Even if C++ returns by value, CABI is returning a heap copy (new'd, not malloc'd)
|
// 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
|
// return "void" // Handled separately with an _out pointer
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -77,10 +83,8 @@ func emitReturnTypeCabi(p CppParameter) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p CppParameter) RenderTypeQtCpp() string {
|
func (p CppParameter) RenderTypeQtCpp() string {
|
||||||
cppType := p.ParameterType
|
cppType := p.UnderlyingType()
|
||||||
if len(p.TypeAlias) > 0 {
|
|
||||||
cppType = p.TypeAlias // replace
|
|
||||||
}
|
|
||||||
if p.Const {
|
if p.Const {
|
||||||
cppType = "const " + cppType
|
cppType = "const " + cppType
|
||||||
}
|
}
|
||||||
@ -147,13 +151,13 @@ func emitParametersCabi(m CppMethod, selfType string) string {
|
|||||||
} else if (p.ByRef || p.Pointer) && p.QtClassType() {
|
} else if (p.ByRef || p.Pointer) && p.QtClassType() {
|
||||||
// Pointer to Qt type
|
// Pointer to Qt type
|
||||||
// Replace with taking our PQ typedef by value
|
// 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() {
|
} else if p.QtClassType() {
|
||||||
// Qt type passed by value
|
// Qt type passed by value
|
||||||
// The CABI will unconditionally take these by pointer and dereference them
|
// The CABI will unconditionally take these by pointer and dereference them
|
||||||
// when passing to C++
|
// when passing to C++
|
||||||
tmp = append(tmp, p.ParameterType+"* "+p.ParameterName)
|
tmp = append(tmp, cabiClassName(p.ParameterType)+"* "+p.ParameterName)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// RenderTypeCabi renders both pointer+reference as pointers
|
// 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
|
// Use the raw ParameterType to select an explicit integer overload
|
||||||
// Don't use RenderTypeCabi() since it canonicalizes some int types for CABI
|
// Don't use RenderTypeCabi() since it canonicalizes some int types for CABI
|
||||||
castSrc := p.ParameterName
|
castSrc := p.ParameterName
|
||||||
castType := p.ParameterType
|
castType := p.RenderTypeQtCpp()
|
||||||
if p.Pointer {
|
|
||||||
castType += "*"
|
|
||||||
}
|
|
||||||
if p.ByRef { // e.g. QDataStream::operator>>() overloads
|
if p.ByRef { // e.g. QDataStream::operator>>() overloads
|
||||||
castSrc = "*" + castSrc
|
castSrc = "*" + castSrc
|
||||||
castType += "&" // believe it or not, this is legal
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.ParameterType == "qint64" || p.ParameterType == "quint64" || p.ParameterType == "qlonglong" || p.ParameterType == "qulonglong" {
|
if p.ParameterType == "qint64" || p.ParameterType == "quint64" || p.ParameterType == "qlonglong" || p.ParameterType == "qulonglong" {
|
||||||
|
@ -88,7 +88,13 @@ func (p CppParameter) RenderTypeGo() string {
|
|||||||
default:
|
default:
|
||||||
|
|
||||||
if strings.Contains(p.ParameterType, `::`) {
|
if strings.Contains(p.ParameterType, `::`) {
|
||||||
ret += "int"
|
if _, ok := KnownClassnames[p.ParameterType]; ok {
|
||||||
|
// Inner class
|
||||||
|
ret += cabiClassName(p.ParameterType)
|
||||||
|
} else {
|
||||||
|
// Enum
|
||||||
|
ret += "uintptr"
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Do not transform this type
|
// Do not transform this type
|
||||||
ret += p.ParameterType
|
ret += p.ParameterType
|
||||||
@ -314,7 +320,7 @@ import "C"
|
|||||||
localInit := "h: h"
|
localInit := "h: h"
|
||||||
for _, base := range c.Inherits {
|
for _, base := range c.Inherits {
|
||||||
gfs.imports["unsafe"] = struct{}{}
|
gfs.imports["unsafe"] = struct{}{}
|
||||||
localInit += ", " + base + ": new" + base + "_U(unsafe.Pointer(h))"
|
localInit += ", " + base + ": new" + cabiClassName(base) + "_U(unsafe.Pointer(h))"
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.WriteString(`
|
ret.WriteString(`
|
||||||
@ -419,9 +425,9 @@ import "C"
|
|||||||
if t.QtClassType() {
|
if t.QtClassType() {
|
||||||
if !t.Pointer {
|
if !t.Pointer {
|
||||||
// new, but then dereference it
|
// 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 {
|
} else {
|
||||||
afterword += "ret[i] = new" + t.ParameterType + "(_outCast[i])\n"
|
afterword += "ret[i] = new" + cabiClassName(t.ParameterType) + "(_outCast[i])\n"
|
||||||
}
|
}
|
||||||
} else { // plain int type
|
} else { // plain int type
|
||||||
afterword += "ret[i] = (" + t.RenderTypeGo() + ")(_outCast[i])\n"
|
afterword += "ret[i] = (" + t.RenderTypeGo() + ")(_outCast[i])\n"
|
||||||
@ -437,7 +443,7 @@ import "C"
|
|||||||
|
|
||||||
if m.ReturnType.Pointer || m.ReturnType.ByRef {
|
if m.ReturnType.Pointer || m.ReturnType.ByRef {
|
||||||
gfs.imports["unsafe"] = struct{}{}
|
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 {
|
} else {
|
||||||
// This is return by value, but CABI has new'd it into a
|
// This is return by value, but CABI has new'd it into a
|
||||||
@ -449,8 +455,8 @@ import "C"
|
|||||||
|
|
||||||
gfs.imports["runtime"] = struct{}{}
|
gfs.imports["runtime"] = struct{}{}
|
||||||
afterword = "// Qt uses pass-by-value semantics for this type. Mimic with finalizer\n"
|
afterword = "// Qt uses pass-by-value semantics for this type. Mimic with finalizer\n"
|
||||||
afterword += "ret1 := new" + m.ReturnType.ParameterType + "(ret)\n"
|
afterword += "ret1 := new" + cabiClassName(m.ReturnType.ParameterType) + "(ret)\n"
|
||||||
afterword += "runtime.SetFinalizer(ret1, func(ret2 *" + m.ReturnType.ParameterType + ") {\n"
|
afterword += "runtime.SetFinalizer(ret1, func(ret2 *" + cabiClassName(m.ReturnType.ParameterType) + ") {\n"
|
||||||
afterword += "ret2.Delete()\n"
|
afterword += "ret2.Delete()\n"
|
||||||
afterword += "runtime.KeepAlive(ret2.h)\n"
|
afterword += "runtime.KeepAlive(ret2.h)\n"
|
||||||
afterword += "})\n"
|
afterword += "})\n"
|
||||||
|
@ -5,6 +5,14 @@ import (
|
|||||||
"strings"
|
"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 {
|
type CppParameter struct {
|
||||||
ParameterName string
|
ParameterName string
|
||||||
ParameterType string
|
ParameterType string
|
||||||
@ -15,8 +23,30 @@ type CppParameter struct {
|
|||||||
Optional bool
|
Optional bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *CppParameter) UnderlyingType() string {
|
||||||
|
if p.TypeAlias != "" {
|
||||||
|
return p.TypeAlias
|
||||||
|
}
|
||||||
|
|
||||||
|
return p.ParameterType
|
||||||
|
}
|
||||||
|
|
||||||
func (p CppParameter) QtClassType() bool {
|
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) {
|
func (p CppParameter) QListOf() (CppParameter, bool) {
|
||||||
|
@ -136,6 +136,11 @@ func main() {
|
|||||||
astTransformOptional(parsed)
|
astTransformOptional(parsed)
|
||||||
astTransformOverloads(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)
|
processHeaders = append(processHeaders, parsed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user