Add a marker for post-C++17 APIs in exported classes

MSVC will export any function in an exported class, including inline
ones. Conversely: client code calling inline functions in imported
classes will end up simply calling the symbol of the function, even if
the function is fully inline.

This is a problem for adding post-C++17 APIs in Qt. Such APIs are added
as inline functions protected by feature-macro tests, so that both Qt
and client apps can use any C++ version they want (any combination
works).

However, if we add a function using post-C++17 API to an exported class,
then the combination "Qt built in C++17" + "client built in post-C++17"
won't work any more. The client will expect the symbol for that function
to be exported by Qt, but Qt won't have it (built in C++17).

As a workaround, add a marker that turns these functions into "faux
templates", like Q_WEAK_OVERLOAD does.

Change-Id: I2adab81e3129c881c5a8e0772948b176fa4db1b6
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Giuseppe D'Angelo 2022-04-06 16:39:22 +02:00
parent 251e9f0bed
commit e996253774
2 changed files with 21 additions and 0 deletions

View File

@ -162,6 +162,7 @@ Cpp.ignoretokens += \
QT_FASTCALL \
QT_MUTEX_LOCK_NOEXCEPT \
QT_POPCOUNT_CONSTEXPR \
QT_POST_CXX17_API_IN_EXPORTED_CLASS \
QT_SIZEPOLICY_CONSTEXPR \
QT_WARNING_DISABLE_DEPRECATED \
QT_WARNING_PUSH \

View File

@ -1206,6 +1206,26 @@
*/
#define Q_WEAK_OVERLOAD template <typename = void>
/*
* If one wants to add functions that use post-C++17 APIs, one needs to:
*
* 1) make them fully inline; and
* 2) guard them using the necessary feature-testing macros.
*
* This decouples the C++ version used to build Qt with the one used by
* end-user applications; Qt and the application can either choose any C++
* version.
*
* A problem arises on MSVC for member functions of exported classes. Client
* code that tries to use such a function will see it as exported, and simply
* try to consume the function's *symbol*. However, if Qt has been built in
* C++17, it won't have such a symbol, and linking will fail.
*
* The workaround: declare such functions as function templates.
* (Obviously a function template does not need this marker.)
*/
#define QT_POST_CXX17_API_IN_EXPORTED_CLASS template <typename = void>
/*
* Warning/diagnostic handling
*/