summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/docs/cpp11-migrate.rst
blob: 48ad12b41914328085f0f13202806e0817e58696 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
===========================
cpp11-migrate User's Manual
===========================

.. toctree::
   :hidden:

   UseAutoTransform

:program:`cpp11-migrate` is a standalone tool used to automatically convert
C++98 and C++03 code to use features of the new C++11 standard where
appropriate.

Basic Usage
===========

``cpp11-migrate [options] <source0> [... <sourceN>]``

``<source0>...`` specify the paths of files in the CMake source tree,
with the same requirements as other tools built on LibTooling.

Command Line Options
--------------------

.. option:: -fatal-assembler-warnings

  Treat all compiler warnings as errors.

.. option:: -help

  Displays tool usage instructions and command line options.

.. option:: -loop-convert

  Makes use of C++11 range-based for loops where possible.
  See :ref:`loop-convert-transformation`.

.. option:: -use-auto

  Replace the type specifier of variable declarations with the ``auto`` type
  specifier. See :doc:`UseAutoTransform`.

.. option:: -p=<build-path>

  ``<build-path>`` is a CMake build directory containing a file named
  ``compile_commands.json`` which provides compiler options for building
  each source file and can be generated by specifying
  ``-DCMAKE_EXPORT_COMPILE_COMMANDS`` when running CMake. If ``<build-path>``
  is not provided the ``compile_commands.json`` file is searched for through
  all parent directories.

  Alternatively, one can provide compile options to be applied to every
  source file after the optional ``--``.

.. option:: -risk=<risk-level>

  Some transformations may cause a change in semantics. In such cases the
  maximum acceptable risk level specified through the ``-risk`` command
  line option decides whether or not a transformation is applied.

  Three different risk level options are available:

    ``-risk=safe``
      Perform only safe transformations.
    ``-risk=reasonable`` (default)
      Enable transformations that may change semantics.
    ``-risk=risky``
      Enable transformations that are likely to change semantics.

  See :ref:`transformations` for further details for
  risk in individual transformations.

.. option:: -use-nullptr

  Makes use of the new C++11 keyword ``nullptr`` where possible.
  See :ref:`nullptr-convert-transformation`.

.. option:: -version

  Displays the version information of this tool.

.. _transformations:

Transformations
===============

.. _loop-convert-transformation:

Loop Convert
------------

Loop convert is a transformation to convert ``for(...; ...; ...)`` loops to use
the new range-based loops in C++11.

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;

.. _nullptr-convert-transformation:

Nullptr Convert
---------------

Nullptr convert is a transformation to convert the usage of null pointer
constants (eg. ``NULL``, ``0``) to use the new C++11 ``nullptr`` keyword.

Example
^^^^^^^

Original
""""""""

.. code-block:: c++

  void assignment() {
    char *a = NULL;
    char *b = 0;
    char c = 0;
  }

  int *ret_ptr() {
    return 0;
  }


After transformation
""""""""""""""""""""

.. code-block:: c++

  void assignment() {
    char *a = nullptr;
    char *b = nullptr;
    char c = 0;
  }

  int *ret_ptr() {
    return nullptr;
  }
OpenPOWER on IntegriCloud