diff --git a/cmd/genbindings/clang2il.go b/cmd/genbindings/clang2il.go index c8d69464..cea3db8a 100644 --- a/cmd/genbindings/clang2il.go +++ b/cmd/genbindings/clang2il.go @@ -146,6 +146,7 @@ func parseHeader(topLevel []interface{}) (*CppParsedHeader, error) { func processClassType(node map[string]interface{}, className string) (CppClass, error) { var ret CppClass ret.ClassName = className + ret.CanDelete = true inner, _ := node["inner"].([]interface{}) // Cannot fail, the parent call already checked that `inner` was present @@ -241,7 +242,7 @@ nextMethod: } // Check if this is `= delete` - if explicitlyDeleted, ok := node["explicitlyDeleted"].(bool); ok && explicitlyDeleted { + if isExplicitlyDeleted(node) { continue } @@ -270,6 +271,19 @@ nextMethod: case "CXXDestructorDecl": // We don't need to expose destructors in the binding beyond offering // a regular delete function + // However if this destructor is private or deleted, we should + // not bind it + + if !visibility { + ret.CanDelete = false + continue + } + + // Check if this is `= delete` + if isExplicitlyDeleted(node) { + ret.CanDelete = false + continue + } case "CXXMethodDecl": if !visibility { @@ -277,7 +291,7 @@ nextMethod: } // Check if this is `= delete` - if explicitlyDeleted, ok := node["explicitlyDeleted"].(bool); ok && explicitlyDeleted { + if isExplicitlyDeleted(node) { continue } @@ -334,6 +348,20 @@ nextMethod: return ret, nil // done } +// isExplicitlyDeleted checks if this node is marked `= delete`. +func isExplicitlyDeleted(node map[string]interface{}) bool { + + if explicitlyDeleted, ok := node["explicitlyDeleted"].(bool); ok && explicitlyDeleted { + return true + } + + if explicitlyDefaulted, ok := node["explicitlyDefaulted"].(string); ok && explicitlyDefaulted == "deleted" { + return true + } + + return false +} + var ErrTooComplex error = errors.New("Type declaration is too complex to parse") func parseMethod(node map[string]interface{}, mm *CppMethod) error { diff --git a/cmd/genbindings/emitcabi.go b/cmd/genbindings/emitcabi.go index f06705e9..a2e298d0 100644 --- a/cmd/genbindings/emitcabi.go +++ b/cmd/genbindings/emitcabi.go @@ -394,7 +394,7 @@ extern "C" { } // delete - if AllowDelete(c) { + if c.CanDelete { ret.WriteString(fmt.Sprintf("void %s_Delete(%s* self);\n", c.ClassName, c.ClassName)) } @@ -562,7 +562,7 @@ extern "C" { } // Delete - if AllowDelete(c) { + if c.CanDelete { ret.WriteString(fmt.Sprintf( "void %s_Delete(%s* self) {\n"+ "\tdelete self;\n"+ diff --git a/cmd/genbindings/emitgo.go b/cmd/genbindings/emitgo.go index edcf85e9..55a4105e 100644 --- a/cmd/genbindings/emitgo.go +++ b/cmd/genbindings/emitgo.go @@ -400,7 +400,7 @@ import "C" } } - if AllowDelete(c) { + if c.CanDelete { ret.WriteString(` func (this *` + c.ClassName + `) Delete() { C.` + c.ClassName + `_Delete(this.h) diff --git a/cmd/genbindings/exceptions.go b/cmd/genbindings/exceptions.go index 56f816c1..335df434 100644 --- a/cmd/genbindings/exceptions.go +++ b/cmd/genbindings/exceptions.go @@ -39,18 +39,6 @@ func AllowHeader(fullpath string) bool { return true } -func AllowDelete(c CppClass) bool { - switch c.ClassName { - case "QClipboard", - "QSessionManager", - "QTextObject", - "QTextBlockGroup", - "QInputMethod": - return false // The destructor is marked private. TODO grab this from the AST - } - return true -} - func ImportHeaderForClass(className string) bool { if className[0] != 'Q' { return false diff --git a/cmd/genbindings/intermediate.go b/cmd/genbindings/intermediate.go index 234504a8..13a2f6a2 100644 --- a/cmd/genbindings/intermediate.go +++ b/cmd/genbindings/intermediate.go @@ -169,6 +169,7 @@ type CppClass struct { Inherits []string // other class names Methods []CppMethod Props []CppProperty + CanDelete bool } type CppTypedef struct {