Add suffixes to loop variables for Q_FOREACH

Currently using nested Q_FOREACH loops produces warnings about
shadowing local variables (if enabled). For example, this code:

    QList<int> aList;
    QList<int> bList;
    foreach (int a, aList) {
        Q_UNUSED(a);
        foreach (int b, bList)
            Q_UNUSED(b);
    }

produces the following warning with MSVC:

    warning C4456: declaration of '_container_' hides previous local
    declaration

This is due to using variable _container_ as loop variable for both
loops.

This patch appends current line number to the name of the loop
variables so that most of the uses of Q_FOREACH will not result
in shadowing.

The patch originally by Benoit Regrain.

Fixes: QTBUG-79081
Pick-to: 5.15 6.2
Change-Id: I55235e917e920171b138c8b3239a95dfe2ac7988
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Ievgenii Meshcheriakov 2021-10-11 14:27:17 +02:00
parent 8b09c9d690
commit 9940e4812b

View File

@ -1290,10 +1290,15 @@ QForeachContainer<typename std::decay<T>::type> qMakeForeachContainer(T &&t)
// Use C++17 if statement with initializer. User's code ends up in a else so
// scoping of different ifs is not broken
#define Q_FOREACH_IMPL(variable, name, container) \
for (auto name = QtPrivate::qMakeForeachContainer(container); name.i != name.e; ++name.i) \
if (variable = *name.i; false) {} else
#define Q_FOREACH_JOIN(A, B) Q_FOREACH_JOIN_IMPL(A, B)
#define Q_FOREACH_JOIN_IMPL(A, B) A ## B
#define Q_FOREACH(variable, container) \
for (auto _container_ = QtPrivate::qMakeForeachContainer(container); \
_container_.i != _container_.e; ++_container_.i) \
if (variable = *_container_.i; false) {} else
Q_FOREACH_IMPL(variable, Q_FOREACH_JOIN(_container_, __LINE__), container)
#endif // QT_NO_FOREACH
#define Q_FOREVER for(;;)