Skip to content

Close #116: Support type resolution for clang-15+#118

Draft
rcalixte wants to merge 12 commits intomappu:masterfrom
rcalixte:desugared_types
Draft

Close #116: Support type resolution for clang-15+#118
rcalixte wants to merge 12 commits intomappu:masterfrom
rcalixte:desugared_types

Conversation

@rcalixte
Copy link
Contributor

@rcalixte rcalixte commented Jan 3, 2025

@rcalixte
Copy link
Contributor Author

rcalixte commented Jan 3, 2025

I'm working on attaching the full diff with a clean cache now. I'll push it up shortly. In hindsight, I probably should've waited to avoid the build failing. Sorry about that.

@rcalixte
Copy link
Contributor Author

rcalixte commented Jan 4, 2025

Hmm, looking at the diff closer, it seems to remove a few functions. Should those be removed or should we look for re-adding them back in?

They're all in qt6:

  • qbrush
  • qvariantanimation
  • network/qabstractnetworkcache
  • network/qnetworkreply

@mappu
Copy link
Owner

mappu commented Jan 4, 2025

The missing functions do not look very important, we could live without them if it makes clang-19 work.

I think it is fixable -

Here's my (unconfirmed) theory:

Taking qt6 qbrush.h QGradient::Stops as an example, the typedef has changed from

		"type": {
			"desugaredQualType": "QList\u003cstd::pair\u003cdouble, QColor\u003e\u003e",
			"qualType": "QList\u003cQGradientStop\u003e"
		}

With the desugaredQualType, the QGradientStop gets expanded immediately into std::pair, and std::pair is blocklisted 😱 in config-allowlist.go. By comparison, in qt5 this same typedef is present as

		"type": {
			"desugaredQualType": "QVector\u003cQPair\u003cdouble, QColor\u003e\u003e",
			"qualType": "QVector\u003cQGradientStop\u003e"
		}

which is apparently understood better.

In that case, one possible solution would be to remove the block on std::pair. If that's not enough by itself, it may also require handling in intermediate.go QPairOf().

Miqt's comment in config-allowlist.go:318 about QGradientStop is definitely outdated 😄

@rcalixte
Copy link
Contributor Author

rcalixte commented Jan 4, 2025

In that case, one possible solution would be to remove the block on std::pair. If that's not enough by itself, it may also require handling in intermediate.go QPairOf().

Good call. We now have support (however infrequent 😅) for std::pair. It's on my list for after I release what I'm working on to dig into other std:: types that we can bind without too much fuss but this is a good start to tearing down some of those walls I think. Thanks again!

@rcalixte rcalixte force-pushed the desugared_types branch 3 times, most recently from b350bb3 to 7c32809 Compare January 11, 2025 03:11
@mappu
Copy link
Owner

mappu commented Jan 11, 2025

I had another look at this today. The genbindings and std::pair changes all look fine to me 👍 The remaining part of the diff converts many int types (uint64, intptr, ptrdiff) to C types (unsigned long long, etc). This conversion is platform-specific and I think it could fail on Windows where "long" has a different bit size than Linux.

The CI tests win64-qt5 already, and that build passed OK. I updated the CI rules on master, so it will test win32-qt5 and win64-qt6.8 as well.

  • Can you please rebase once more?

If it then passes on all those Windows platforms, then LGTM to merge. But if it doesn't pass we'll need to think more carefully about how int types are handled.

@rcalixte
Copy link
Contributor Author

rcalixte commented Jan 11, 2025

The remaining part of the diff converts many int types (uint64, intptr, ptrdiff) to C types (unsigned long long, etc).

We could always revert these back in emitcabi.go right? I don't mind doing that or reworking the logic for the desugared types. We could skip certain desugared types or just redo the logic entirely. (This would also allow us to re-add that QHashSeed function that was just removed too right?)

@arnetheduck
Copy link
Contributor

We could always revert these back in emitcabi.go right?

Technically the c sources become a little bit more portable if they retain intptr_t etc, ie they better capture the original qt intent - you can't get these back from int, long etc since they are different depending on os/cpu/abi/gcc flags sometimes/etc - above all, if the generated C files are to be used from C, this could be a problem.

@rcalixte
Copy link
Contributor Author

Technically the c sources become a little bit more portable if they retain intptr_t etc, ie they better capture the original qt intent - you can't get these back from int, long etc since they are different depending on os/cpu/abi/gcc flags sometimes/etc - above all, if the generated C files are to be used from C, this could be a problem.

Maybe it's a hack (just wait until you see what I've done 😆), but what if we exclude those types from the desugaring? I'm thinking a conditional for _t types and/or intptr types or something along that course.

@arnetheduck
Copy link
Contributor

I guess one can grab a list from https://pubs.opengroup.org/onlinepubs/009604599/basedefs/stdint.h.html and it would hopefully cover most of it? always a mess with c, finding the right level of de-macro-and-typedef-ification ;) it's not an unreasonable starting point at least.

@rcalixte
Copy link
Contributor Author

rcalixte commented Jan 11, 2025

it's not an unreasonable starting point at least.

I ended up grabbing the Qt typedefs from https://doc.qt.io/qt-6/qttypes.html too. The diff didn't change much without it. The result change in this pull request is now much smaller.

@arnetheduck
Copy link
Contributor

👍

https://pubs.opengroup.org/onlinepubs/7908799/xsh/stddef.h.html is another source, pre-c99 so probably also good to cover

@rcalixte rcalixte closed this Jan 20, 2025
@rcalixte rcalixte reopened this Jan 20, 2025
@rcalixte rcalixte force-pushed the desugared_types branch 4 times, most recently from 33960ee to 24cf11d Compare January 20, 2025 19:37
@rcalixte
Copy link
Contributor Author

rcalixte commented Jul 5, 2025

I had a challenge with what I thought would be a cosmetic change on some container type resolutions. I left them alone because they were the same result but that was on Qt 6. With Qt 5, that isn't going to be an option it seems. Worse yet, this (ugly) patch to fix Qt 5 only works on Debian 12. On Debian 13 or anything with Clang 15+, we're right back where we started. I don't know if it makes sense to split out the two, especially with the issues with the libraries like QTermWidget that don't appear to exist in more than one version simultaneously. Maybe a Qt 5 base pinned to Debian 12 where there are still auxiliary libraries that are compatible with Qt 5? This was why I versioned the repositories for each downstream project.

This end result here leaves me with mixed feelings. First the iterator types and now Qt 5. Let me know how you want to proceed. I should have the Qt 6.8 base pushed to the downstreams by the end of this weekend if you want to take a look at anything there.

@rcalixte rcalixte force-pushed the desugared_types branch 2 times, most recently from 298d51c to 4eccf9a Compare July 5, 2025 14:10
@rcalixte rcalixte force-pushed the desugared_types branch 4 times, most recently from a0bf00d to 32f2bf9 Compare July 5, 2025 22:22
@rcalixte
Copy link
Contributor Author

rcalixte commented Jul 5, 2025

Starting from the latest changes here, I was able to get a clean build of the helloworld example on a Qt 6.8 base with a few patches that are not part of this pull request:

  • Disabling the build for Qt 5
  • Removing the aforementioned iterator types
  • Patching gen_qflags.cpp with #include <new> to support the usage of std::nothrow
  • Patching gen_qpermissions.* to remove signals that invoke invalid ::connect methods (downstream, I just removed these)
  • Deleting binding.go since QSysInfo::Endian is now properly generated resulting in a duplicate declaration (downstream, quite a few of the manual typedefs/workarounds are cleaned up)

Other examples that don't require any modification for the Qt 6.8 changes also work just fine. There is a curious regression with private signals that I haven't dug into yet but this didn't require any patching downstream so I wonder if something else is leading to the block.

The CI is failing. I can try to patch the fix but I can't replicate it outside of CI so I wonder if it needs to be patched at all.

@rcalixte rcalixte marked this pull request as ready for review July 5, 2025 23:09
@rcalixte rcalixte changed the title clang2il.go: Check for desugared types (support clang-15+) Close #116: Support type resolution for clang-15+ Jul 5, 2025
@rcalixte
Copy link
Contributor Author

rcalixte commented Jul 6, 2025

Last touch up I promise. 😅

@rcalixte
Copy link
Contributor Author

rcalixte commented Jul 6, 2025

There is a curious regression with private signals that I haven't dug into yet but this didn't require any patching downstream so I wonder if something else is leading to the block.

There must be some over-zealous matching done somewhere else that escapes me at the moment. The same definitions and parsing existing in clang2il.go and config-allowlist.go as the downstreams and worse yet, this only appears when run against Qt 6.8 not Qt 6.4. When I comment out the QPrivate and QPrivateSignal conditionals in config-allowlist.go, the private methods incorrectly come through as regular methods (meaning direct invocations in addition to the callbacks). The block otherwise:

Blocking method "timeout"([Param(QPrivateSignal param1)]): Type declaration is too complex to parse

To add to the curiosity, commenting out either one of the checks and leaving the other has no effect.

@rcalixte
Copy link
Contributor Author

rcalixte commented Jul 7, 2025

For Qt 5 on Debian 13, maybe we can get away with some metatype registrations to resolve the typedef differences?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

genbindings doesn't work with clang-19

3 participants