forked from OSchip/llvm-project
121 lines
2.9 KiB
ReStructuredText
121 lines
2.9 KiB
ReStructuredText
.. index:: Loop Convert Transform
|
|
|
|
======================
|
|
Loop Convert Transform
|
|
======================
|
|
|
|
The Loop Convert Transform is a transformation to convert ``for(...; ...;
|
|
...)`` loops to use the new range-based loops in C++11. The transform is enabled
|
|
with the :option:`-loop-convert` option of :program:`cpp11-migrate`.
|
|
|
|
Three kinds of loops can be converted:
|
|
|
|
- Loops over statically allocated arrays
|
|
- Loops over containers, using iterators
|
|
- Loops over array-like containers, using ``operator[]`` and ``at()``
|
|
|
|
Risk
|
|
====
|
|
|
|
TODO: Add code examples for which incorrect transformations are performed
|
|
when the risk level is set to "Risky" or "Reasonable".
|
|
|
|
Risky
|
|
^^^^^
|
|
|
|
In loops where the container expression is more complex than just a
|
|
reference to a declared expression (a variable, function, enum, etc.),
|
|
and some part of it appears elsewhere in the loop, we lower our confidence
|
|
in the transformation due to the increased risk of changing semantics.
|
|
Transformations for these loops are marked as `risky`, and thus will only
|
|
be converted if the acceptable risk level is set to ``-risk=risky``.
|
|
|
|
.. code-block:: c++
|
|
|
|
int arr[10][20];
|
|
int l = 5;
|
|
|
|
for (int j = 0; j < 20; ++j)
|
|
int k = arr[l][j] + l; // using l outside arr[l] is considered risky
|
|
|
|
for (int i = 0; i < obj.getVector().size(); ++i)
|
|
obj.foo(10); // using 'obj' is considered risky
|
|
|
|
Reasonable (Default)
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
If a loop calls ``.end()`` or ``.size()`` after each iteration, the
|
|
transformation for that loop is marked as `reasonable`, and thus will
|
|
be converted if the acceptable risk level is set to ``-risk=reasonable``
|
|
(default) or higher.
|
|
|
|
.. code-block:: c++
|
|
|
|
// using size() is considered reasonable
|
|
for (int i = 0; i < container.size(); ++i)
|
|
cout << container[i];
|
|
|
|
Safe
|
|
^^^^
|
|
|
|
Any other loops that do not match the above criteria to be marked as
|
|
`risky` or `reasonable` are marked `safe`, and thus will be converted
|
|
if the acceptable risk level is set to ``-risk=safe`` or higher.
|
|
|
|
.. code-block:: c++
|
|
|
|
int arr[] = {1,2,3};
|
|
|
|
for (int i = 0; i < 3; ++i)
|
|
cout << arr[i];
|
|
|
|
Example
|
|
=======
|
|
|
|
Original:
|
|
|
|
.. code-block:: c++
|
|
|
|
const int N = 5;
|
|
int arr[] = {1,2,3,4,5};
|
|
vector<int> v;
|
|
v.push_back(1);
|
|
v.push_back(2);
|
|
v.push_back(3);
|
|
|
|
// safe transform
|
|
for (int i = 0; i < N; ++i)
|
|
cout << arr[i];
|
|
|
|
// reasonable transform
|
|
for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
|
|
cout << *it;*
|
|
|
|
// reasonable transform
|
|
for (int i = 0; i < v.size(); ++i)
|
|
cout << v[i];
|
|
|
|
After transformation with risk level set to ``-risk=reasonable`` (default):
|
|
|
|
.. code-block:: c++
|
|
|
|
const int N = 5;
|
|
int arr[] = {1,2,3,4,5};
|
|
vector<int> v;
|
|
v.push_back(1);
|
|
v.push_back(2);
|
|
v.push_back(3);
|
|
|
|
// safe transform
|
|
for (auto & elem : arr)
|
|
cout << elem;
|
|
|
|
// reasonable transform
|
|
for (auto & elem : v)
|
|
cout << elem;
|
|
|
|
// reasonable transform
|
|
for (auto & elem : v)
|
|
cout << elem;
|
|
|