Skip to content

Commit

Permalink
clang2il.go: Check for desugared types (support clang-19+)
Browse files Browse the repository at this point in the history
* Closes mappu#116
  • Loading branch information
rcalixte committed Jan 11, 2025
1 parent 3d864cd commit 46e9061
Show file tree
Hide file tree
Showing 229 changed files with 1,115 additions and 1,061 deletions.
81 changes: 71 additions & 10 deletions cmd/genbindings/clang2il.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,29 @@ nextTopLevel:
return &ret, nil // done
}

// shouldPreferQualType returns true if we should use the qualType instead of
// the desugared type based on certain type patterns
func shouldPreferQualType(qualType string) bool {
if strings.Contains(qualType, "intptr") || strings.Contains(qualType, "_t") ||
strings.HasPrefix(qualType, "uint") || strings.Contains(qualType, "ushort") ||
strings.Contains(qualType, "quint") || strings.Contains(qualType, "qint") ||
strings.Contains(qualType, "qptrdiff") || strings.HasPrefix(qualType, "qsize") {
return true
}
return false
}

// getPreferredType returns either the desugared type or qual type based on our rules
func getPreferredType(desugared, qualType string) string {
if qualType != "" && shouldPreferQualType(qualType) {
return qualType
}
if desugared != "" {
return desugared
}
return qualType
}

// processTypedef parses a single C++ typedef into our intermediate format.
func processTypedef(node map[string]interface{}, addNamePrefix string) (CppTypedef, error) {
// Must have a name
Expand All @@ -174,7 +197,17 @@ func processTypedef(node map[string]interface{}, addNamePrefix string) (CppTyped
}

if typ, ok := node["type"].(map[string]interface{}); ok {
if qualType, ok := typ["qualType"].(string); ok {
// Try desugaredQualType first
var desugared, qualType string
if d, ok := typ["desugaredQualType"].(string); ok {
desugared = d
}
if q, ok := typ["qualType"].(string); ok {
qualType = q
}
qualType = getPreferredType(desugared, qualType)

if qualType != "" {
return CppTypedef{
Alias: addNamePrefix + nodename,
UnderlyingType: parseSingleTypeString(qualType),
Expand Down Expand Up @@ -264,7 +297,15 @@ func processClassType(node map[string]interface{}, addNamePrefix string) (CppCla
}

if typ, ok := base["type"].(map[string]interface{}); ok {
if qualType, ok := typ["qualType"].(string); ok {
var desugared, qualType string
if d, ok := typ["desugaredQualType"].(string); ok {
desugared = d
}
if q, ok := typ["qualType"].(string); ok {
qualType = q
}
qualType = getPreferredType(desugared, qualType)
if qualType != "" {
ret.DirectInherits = append(ret.DirectInherits, qualType)
}
}
Expand Down Expand Up @@ -512,8 +553,16 @@ func processEnum(node map[string]interface{}, addNamePrefix string) (CppEnum, er
// Underlying type
ret.UnderlyingType = parseSingleTypeString("int")
if nodefut, ok := node["fixedUnderlyingType"].(map[string]interface{}); ok {
if nodequal, ok := nodefut["qualType"].(string); ok {
ret.UnderlyingType = parseSingleTypeString(nodequal)
var desugared, qualType string
if d, ok := nodefut["desugaredQualType"].(string); ok {
desugared = d
}
if q, ok := nodefut["qualType"].(string); ok {
qualType = q
}
qualType = getPreferredType(desugared, qualType)
if qualType != "" {
ret.UnderlyingType = parseSingleTypeString(qualType)
}
}

Expand Down Expand Up @@ -650,18 +699,22 @@ nextEnumEntry:

// parseMethod parses a Clang method into our CppMethod intermediate format.
func parseMethod(node map[string]interface{}, mm *CppMethod) error {

if typobj, ok := node["type"].(map[string]interface{}); ok {
if qualType, ok := typobj["qualType"].(string); ok {
// The qualType is the whole type of the method, including its parameter types
// If anything here is too complicated, skip the whole method
var desugared, qualType string
if d, ok := typobj["desugaredQualType"].(string); ok {
desugared = d
}
if q, ok := typobj["qualType"].(string); ok {
qualType = q
}
qualType = getPreferredType(desugared, qualType)

var err error = nil
if qualType != "" {
var err error
mm.ReturnType, mm.Parameters, mm.IsConst, err = parseTypeString(qualType)
if err != nil {
return err
}

}
}

Expand Down Expand Up @@ -691,6 +744,14 @@ func parseMethod(node map[string]interface{}, mm *CppMethod) error {
parmName, _ := methodObj["name"].(string) // n.b. may be unnamed
if parmName == "" {

// Get the precise parameter type if available
if typ, ok := methodObj["type"].(map[string]interface{}); ok {
if desugared, ok := typ["desugaredQualType"].(string); ok {
// Update the parameter type with the more precise desugared version
mm.Parameters[paramCounter].ParameterType = desugared
}
}

// Generate a default parameter name
// Super nice autogen names if this is a Q_PROPERTY setter:
if len(mm.Parameters) == 1 && strings.HasPrefix(mm.MethodName, "set") {
Expand Down
4 changes: 2 additions & 2 deletions cmd/genbindings/config-allowlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func AllowClass(className string) bool {
return false
}

if strings.HasPrefix(className, `std::`) {
if strings.HasPrefix(className, `std::`) && !strings.HasPrefix(className, `std::pair`) {
return false // Scintilla bindings find some of these
}

Expand Down Expand Up @@ -408,7 +408,7 @@ func AllowType(p CppParameter, isReturnType bool) error {
return ErrTooComplex // Function pointer types in QtWebEngine
}

if strings.HasPrefix(p.ParameterType, "std::") {
if strings.HasPrefix(p.ParameterType, "std::") && !strings.HasPrefix(p.ParameterType, `std::pair<`) {
// std::initializer e.g. qcborarray.h
// std::string QByteArray->toStdString(). There are QString overloads already
// std::nullptr_t Qcborstreamwriter
Expand Down
9 changes: 7 additions & 2 deletions cmd/genbindings/intermediate.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,13 @@ func (p CppParameter) QMapOf() (CppParameter, CppParameter, bool) {
}

func (p CppParameter) QPairOf() (CppParameter, CppParameter, bool) {
if strings.HasPrefix(p.ParameterType, `QPair<`) && strings.HasSuffix(p.ParameterType, `>`) {
interior := tokenizeMultipleParameters(p.ParameterType[6 : len(p.ParameterType)-1])
if (strings.HasPrefix(p.ParameterType, `QPair<`) || strings.HasPrefix(p.ParameterType, `std::pair<`)) &&
strings.HasSuffix(p.ParameterType, `>`) {
index := 6 // QPair<
if strings.HasPrefix(p.ParameterType, `std::pair<`) {
index = 10 // std::pair<
}
interior := tokenizeMultipleParameters(p.ParameterType[index : len(p.ParameterType)-1])
if len(interior) != 2 {
panic("QPair<> has unexpected number of template arguments")
}
Expand Down
6 changes: 3 additions & 3 deletions cmd/genbindings/util.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package main

import (
"strconv"
"encoding/json"
"log"
"strconv"
"strings"
)

Expand All @@ -12,7 +12,7 @@ func maybeSuffix(counter int) string {
return ""
}

return strconv.Itoa(counter+1)
return strconv.Itoa(counter + 1)
}

func titleCase(s string) string {
Expand Down Expand Up @@ -53,4 +53,4 @@ func slice_copy[T comparable](input []T) []T {
ret[i] = elem
}
return ret
}
}
8 changes: 4 additions & 4 deletions qt/gen_qabstractitemmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,9 @@ int QModelIndex_Column(const QModelIndex* self) {
return self->column();
}

uintptr_t QModelIndex_InternalId(const QModelIndex* self) {
unsigned long long QModelIndex_InternalId(const QModelIndex* self) {
quintptr _ret = self->internalId();
return static_cast<uintptr_t>(_ret);
return static_cast<unsigned long long>(_ret);
}

void* QModelIndex_InternalPointer(const QModelIndex* self) {
Expand Down Expand Up @@ -290,9 +290,9 @@ void* QPersistentModelIndex_InternalPointer(const QPersistentModelIndex* self) {
return self->internalPointer();
}

uintptr_t QPersistentModelIndex_InternalId(const QPersistentModelIndex* self) {
unsigned long long QPersistentModelIndex_InternalId(const QPersistentModelIndex* self) {
quintptr _ret = self->internalId();
return static_cast<uintptr_t>(_ret);
return static_cast<unsigned long long>(_ret);
}

QModelIndex* QPersistentModelIndex_Parent(const QPersistentModelIndex* self) {
Expand Down
8 changes: 4 additions & 4 deletions qt/gen_qabstractitemmodel.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ func (this *QModelIndex) Column() int {
return (int)(C.QModelIndex_Column(this.h))
}

func (this *QModelIndex) InternalId() uintptr {
return (uintptr)(C.QModelIndex_InternalId(this.h))
func (this *QModelIndex) InternalId() uint64 {
return (uint64)(C.QModelIndex_InternalId(this.h))
}

func (this *QModelIndex) InternalPointer() unsafe.Pointer {
Expand Down Expand Up @@ -281,8 +281,8 @@ func (this *QPersistentModelIndex) InternalPointer() unsafe.Pointer {
return (unsafe.Pointer)(C.QPersistentModelIndex_InternalPointer(this.h))
}

func (this *QPersistentModelIndex) InternalId() uintptr {
return (uintptr)(C.QPersistentModelIndex_InternalId(this.h))
func (this *QPersistentModelIndex) InternalId() uint64 {
return (uint64)(C.QPersistentModelIndex_InternalId(this.h))
}

func (this *QPersistentModelIndex) Parent() *QModelIndex {
Expand Down
4 changes: 2 additions & 2 deletions qt/gen_qabstractitemmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ QModelIndex* QModelIndex_new();
QModelIndex* QModelIndex_new2(QModelIndex* param1);
int QModelIndex_Row(const QModelIndex* self);
int QModelIndex_Column(const QModelIndex* self);
uintptr_t QModelIndex_InternalId(const QModelIndex* self);
unsigned long long QModelIndex_InternalId(const QModelIndex* self);
void* QModelIndex_InternalPointer(const QModelIndex* self);
QModelIndex* QModelIndex_Parent(const QModelIndex* self);
QModelIndex* QModelIndex_Sibling(const QModelIndex* self, int row, int column);
Expand Down Expand Up @@ -82,7 +82,7 @@ QModelIndex* QPersistentModelIndex_ToConstQModelIndexBitwiseAnd(const QPersisten
int QPersistentModelIndex_Row(const QPersistentModelIndex* self);
int QPersistentModelIndex_Column(const QPersistentModelIndex* self);
void* QPersistentModelIndex_InternalPointer(const QPersistentModelIndex* self);
uintptr_t QPersistentModelIndex_InternalId(const QPersistentModelIndex* self);
unsigned long long QPersistentModelIndex_InternalId(const QPersistentModelIndex* self);
QModelIndex* QPersistentModelIndex_Parent(const QPersistentModelIndex* self);
QModelIndex* QPersistentModelIndex_Sibling(const QPersistentModelIndex* self, int row, int column);
QModelIndex* QPersistentModelIndex_Child(const QPersistentModelIndex* self, int row, int column);
Expand Down
2 changes: 1 addition & 1 deletion qt/gen_qfont.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ double QFont_PointSizeF(const QFont* self) {
}

void QFont_SetPointSizeF(QFont* self, double pointSizeF) {
self->setPointSizeF(static_cast<qreal>(pointSizeF));
self->setPointSizeF(static_cast<double>(pointSizeF));
}

int QFont_PixelSize(const QFont* self) {
Expand Down
2 changes: 1 addition & 1 deletion qt/gen_qgraphicssceneevent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ int QGraphicsSceneMouseEvent_Flags(const QGraphicsSceneMouseEvent* self) {
}

void QGraphicsSceneMouseEvent_SetFlags(QGraphicsSceneMouseEvent* self, int flags) {
self->setFlags(static_cast<Qt::MouseEventFlags>(flags));
self->setFlags(static_cast<QFlags<Qt::MouseEventFlag>>(flags));
}

void QGraphicsSceneMouseEvent_Delete(QGraphicsSceneMouseEvent* self, bool isSubclass) {
Expand Down
8 changes: 4 additions & 4 deletions qt/gen_qgraphicstransform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ double QGraphicsScale_XScale(const QGraphicsScale* self) {
}

void QGraphicsScale_SetXScale(QGraphicsScale* self, double xScale) {
self->setXScale(static_cast<qreal>(xScale));
self->setXScale(static_cast<double>(xScale));
}

double QGraphicsScale_YScale(const QGraphicsScale* self) {
Expand All @@ -495,7 +495,7 @@ double QGraphicsScale_YScale(const QGraphicsScale* self) {
}

void QGraphicsScale_SetYScale(QGraphicsScale* self, double yScale) {
self->setYScale(static_cast<qreal>(yScale));
self->setYScale(static_cast<double>(yScale));
}

double QGraphicsScale_ZScale(const QGraphicsScale* self) {
Expand All @@ -504,7 +504,7 @@ double QGraphicsScale_ZScale(const QGraphicsScale* self) {
}

void QGraphicsScale_SetZScale(QGraphicsScale* self, double zScale) {
self->setZScale(static_cast<qreal>(zScale));
self->setZScale(static_cast<double>(zScale));
}

void QGraphicsScale_ApplyTo(const QGraphicsScale* self, QMatrix4x4* matrix) {
Expand Down Expand Up @@ -711,7 +711,7 @@ double QGraphicsRotation_Angle(const QGraphicsRotation* self) {
}

void QGraphicsRotation_SetAngle(QGraphicsRotation* self, double angle) {
self->setAngle(static_cast<qreal>(angle));
self->setAngle(static_cast<double>(angle));
}

QVector3D* QGraphicsRotation_Axis(const QGraphicsRotation* self) {
Expand Down
10 changes: 5 additions & 5 deletions qt/gen_qgridlayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -733,19 +733,19 @@ struct miqt_string QGridLayout_TrUtf83(const char* s, const char* c, int n) {
}

void QGridLayout_AddWidget4(QGridLayout* self, QWidget* param1, int row, int column, int param4) {
self->addWidget(param1, static_cast<int>(row), static_cast<int>(column), static_cast<Qt::Alignment>(param4));
self->addWidget(param1, static_cast<int>(row), static_cast<int>(column), static_cast<QFlags<Qt::AlignmentFlag>>(param4));
}

void QGridLayout_AddWidget6(QGridLayout* self, QWidget* param1, int row, int column, int rowSpan, int columnSpan, int param6) {
self->addWidget(param1, static_cast<int>(row), static_cast<int>(column), static_cast<int>(rowSpan), static_cast<int>(columnSpan), static_cast<Qt::Alignment>(param6));
self->addWidget(param1, static_cast<int>(row), static_cast<int>(column), static_cast<int>(rowSpan), static_cast<int>(columnSpan), static_cast<QFlags<Qt::AlignmentFlag>>(param6));
}

void QGridLayout_AddLayout4(QGridLayout* self, QLayout* param1, int row, int column, int param4) {
self->addLayout(param1, static_cast<int>(row), static_cast<int>(column), static_cast<Qt::Alignment>(param4));
self->addLayout(param1, static_cast<int>(row), static_cast<int>(column), static_cast<QFlags<Qt::AlignmentFlag>>(param4));
}

void QGridLayout_AddLayout6(QGridLayout* self, QLayout* param1, int row, int column, int rowSpan, int columnSpan, int param6) {
self->addLayout(param1, static_cast<int>(row), static_cast<int>(column), static_cast<int>(rowSpan), static_cast<int>(columnSpan), static_cast<Qt::Alignment>(param6));
self->addLayout(param1, static_cast<int>(row), static_cast<int>(column), static_cast<int>(rowSpan), static_cast<int>(columnSpan), static_cast<QFlags<Qt::AlignmentFlag>>(param6));
}

void QGridLayout_AddItem4(QGridLayout* self, QLayoutItem* item, int row, int column, int rowSpan) {
Expand All @@ -757,7 +757,7 @@ void QGridLayout_AddItem5(QGridLayout* self, QLayoutItem* item, int row, int col
}

void QGridLayout_AddItem6(QGridLayout* self, QLayoutItem* item, int row, int column, int rowSpan, int columnSpan, int param6) {
self->addItem(item, static_cast<int>(row), static_cast<int>(column), static_cast<int>(rowSpan), static_cast<int>(columnSpan), static_cast<Qt::Alignment>(param6));
self->addItem(item, static_cast<int>(row), static_cast<int>(column), static_cast<int>(rowSpan), static_cast<int>(columnSpan), static_cast<QFlags<Qt::AlignmentFlag>>(param6));
}

void QGridLayout_override_virtual_SizeHint(void* self, intptr_t slot) {
Expand Down
6 changes: 3 additions & 3 deletions qt/gen_qheaderview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -761,14 +761,14 @@ class MiqtVirtualQHeaderView : public virtual QHeaderView {
intptr_t handle__MoveCursor = 0;

// Subclass to allow providing a Go implementation
virtual QModelIndex moveCursor(QAbstractItemView::CursorAction param1, Qt::KeyboardModifiers param2) override {
virtual QModelIndex moveCursor(QAbstractItemView::CursorAction param1, QFlags<Qt::KeyboardModifier> param2) override {
if (handle__MoveCursor == 0) {
return QHeaderView::moveCursor(param1, param2);
}

QAbstractItemView::CursorAction param1_ret = param1;
int sigval1 = static_cast<int>(param1_ret);
Qt::KeyboardModifiers param2_ret = param2;
QFlags<Qt::KeyboardModifier> param2_ret = param2;
int sigval2 = static_cast<int>(param2_ret);

QModelIndex* callback_return_value = miqt_exec_callback_QHeaderView_MoveCursor(this, handle__MoveCursor, sigval1, sigval2);
Expand All @@ -779,7 +779,7 @@ class MiqtVirtualQHeaderView : public virtual QHeaderView {
// Wrapper to allow calling protected method
QModelIndex* virtualbase_MoveCursor(int param1, int param2) {

return new QModelIndex(QHeaderView::moveCursor(static_cast<QAbstractItemView::CursorAction>(param1), static_cast<Qt::KeyboardModifiers>(param2)));
return new QModelIndex(QHeaderView::moveCursor(static_cast<QAbstractItemView::CursorAction>(param1), static_cast<QFlags<Qt::KeyboardModifier>>(param2)));

}

Expand Down
2 changes: 1 addition & 1 deletion qt/gen_qlabel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ int QLabel_Alignment(const QLabel* self) {
}

void QLabel_SetAlignment(QLabel* self, int alignment) {
self->setAlignment(static_cast<Qt::Alignment>(alignment));
self->setAlignment(static_cast<QFlags<Qt::AlignmentFlag>>(alignment));
}

void QLabel_SetWordWrap(QLabel* self, bool on) {
Expand Down
Loading

0 comments on commit 46e9061

Please sign in to comment.