1=====================================
2Formatting C++ Code With clang-format
3=====================================
4
5Mozilla uses the Google coding style for whitespace, which is enforced
6using `clang-format <https://clang.llvm.org/docs/ClangFormat.html>`__. A
7specific version of the binary will be installed when
8``./mach clang-format`` or ``./mach bootstrap`` are run. We build our
9own binaries and update them as needed.
10
11Options are explicitly defined `in clang-format
12itself <https://github.com/llvm-mirror/clang/blob/e8a55f98df6bda77ee2eaa7f7247bd655f79ae0e/lib/Format/Format.cpp#L856>`__.
13If the options are changed in clang upstream, this might cause some
14changes in the Firefox tree. For this reason, it is best to use the
15mozilla-provided binaries.
16
17Manual formatting
18-----------------
19
20We provide a mach subcommand for running clang-format from the
21command-line. This wrapper handles ensuring the correct version of
22clang-format is installed and run.
23
24If clang-format isn’t installed, the binaries will be automatically
25downloaded from taskcluster and installed into ~/.mozbuild. We build our
26own clang-format binaries.
27
28
29Formatting local changes
30~~~~~~~~~~~~~~~~~~~~~~~~
31
32::
33
34   $ ./mach clang-format
35
36When run without arguments, it will run on a local diff. This could miss
37some reformatting (for example, when blocks are touched).
38(`searchfox <https://searchfox.org/mozilla-central/rev/501eb4718d73870892d28f31a99b46f4783efaa0/python/mozbuild/mozbuild/code-analysis/mach_commands.py#1620>`__)
39
40
41Formatting specific paths
42~~~~~~~~~~~~~~~~~~~~~~~~~
43
44::
45
46   $ ./mach clang-format -p <path>     # Format <path> in-place
47   $ ./mach clang-format -p <path> -s  # Show changes
48
49The command also accepts a ``-p`` argument to reformat a specific
50directory or file, and a ``-s`` flag to show the changes instead of
51applying them to the working directory
52(`searchfox <https://searchfox.org/mozilla-central/rev/501eb4718d73870892d28f31a99b46f4783efaa0/python/mozbuild/mozbuild/code-analysis/mach_commands.py#1633>`__)
53
54
55Formatting specific commits / revisions
56~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
57
58::
59
60   $ ./mach clang-format -c HEAD # Format a single git commit
61   $ ./mach clang-format -c HEAD~~..HEAD # Format a range of git commits
62   $ ./mach clang-format -c . # Format a single mercurial revision
63
64The command accepts a ``-c`` argument that takes a revision number or
65commit range, and will format the lines modified by those commits.
66(`searchfox <https://searchfox.org/mozilla-central/rev/501eb4718d73870892d28f31a99b46f4783efaa0/python/mozbuild/mozbuild/code-analysis/mach_commands.py#1635>`__)
67
68
69Scripting Clang-Format
70~~~~~~~~~~~~~~~~~~~~~~
71
72Clang format expects that the path being passed to it is the path
73on-disk. If this is not the case, for example when formatting a
74temporary file, the "real" path must be specified. This can be done with
75the ``--assume-filename <path>`` argument.
76
77
78Configuring the clang-format commit hook
79~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
80
81To run clang-format at commit phase, run ``mach boostrap`` or just add
82the following line in the ``hgrc`` file:
83
84.. code:: ini
85
86   [extensions]
87   clang-format = ~/.mozbuild/version-control-tools/hgext/clang-format
88
89We use a hg extension as they are more flexible than hooks.
90
91With git, the configuration is the following:
92
93::
94
95   # From the root git directory:
96   $ ln -s $(pwd)/tools/lint/hooks_clang_format.py .git/hooks/pre-commit
97
98You'll likely need to install the ``python-hglib`` package for your OS,
99or else you may get errors like ``abort: No module named hglib.client!``
100when you try to commit.
101
102
103Editor integration
104------------------
105
106It is possible to configure many editors to support running
107``clang-format`` automatically on save, or when run from within the
108editor.
109
110
111Editor plugins
112~~~~~~~~~~~~~~
113
114-  `Atom <https://atom.io/packages/clang-format>`__
115-  `BBEdit <http://clang.llvm.org/docs/ClangFormat.html#bbedit-integration>`__
116
117   -  `clang-format-bbedit.applescript <https://raw.githubusercontent.com/llvm-mirror/clang/master/tools/clang-format/clang-format-bbedit.applescript>`__
118
119-  Eclipse
120
121   -  Install the
122      `CppStyle <https://marketplace.eclipse.org/content/cppstyle>`__
123      plugin
124   -  In Preferences -> C/C++ -> CppStyle, set the clang-format path to
125      ~/.mozbuild/clang-tools/clang-tidy/bin/clang-format
126   -  (Optional) check "Run clang-format on file save"
127
128-  `Emacs <http://clang.llvm.org/docs/ClangFormat.html#emacs-integration>`__
129
130   -  `clang-format.el <https://raw.githubusercontent.com/llvm-mirror/clang/master/tools/clang-format/clang-format.el>`__
131      (Or install
132      `clang-format <http://melpa.org/#/clang-format>`__ from MELPA)
133   -  `google-c-style <http://melpa.org/#/google-c-style>`__ from MELPA
134
135-  `Sublime Text <https://packagecontrol.io/packages/Clang%20Format>`__
136
137   -  `alternative
138      tool <https://github.com/rosshemsley/SublimeClangFormat>`__
139
140-  `Vim <http://clang.llvm.org/docs/ClangFormat.html#vim-integration>`__
141
142   -  `clang-format.py <https://raw.githubusercontent.com/llvm-mirror/clang/master/tools/clang-format/clang-format.py>`__
143   -  `vim-clang-format <https://github.com/rhysd/vim-clang-format>`__
144
145-  `Visual
146   Studio <https://marketplace.visualstudio.com/items?itemName=LLVMExtensions.ClangFormat>`__
147
148   -  `llvm.org plugin <http://llvm.org/builds/>`__
149   -  `Integrated support in Visual Studio
150      2017 <https://blogs.msdn.microsoft.com/vcblog/2018/03/13/clangformat-support-in-visual-studio-2017-15-7-preview-1/>`__
151
152-  `Visual Studio
153   Code <https://marketplace.visualstudio.com/items?itemName=xaver.clang-format>`__
154-  `XCode <https://github.com/travisjeffery/ClangFormat-Xcode>`__
155-  `Script for patch
156   reformatting <http://clang.llvm.org/docs/ClangFormat.html#script-for-patch-reformatting>`__
157
158   -  `clang-format-diff.py <https://raw.githubusercontent.com/llvm-mirror/clang/master/tools/clang-format/clang-format-diff.py>`__
159
160
161Configuration
162~~~~~~~~~~~~~
163
164These tools generally run clang-format themselves, and won't use
165``./mach clang-format``. The binary installed by our tooling will be
166located at ``~/.mozbuild/clang-tools/clang-tidy/bin/clang-format``.
167
168You typically shouldn't need to specify any other special configuration
169in your editor besides the clang-format binary. Most of the
170configuration that clang-format relies on for formatting is stored
171inside our source tree. More specifically, using the .clang-format file
172located in the root of the repository. Please note that this doesn't
173include the list of ignored files and directories (provided by
174.clang-format-ignore which is a feature provided by the mach command
175wrapper).
176
177Coding style configuration is done within clang-format itself. When we
178change the configuration (incorrect configuration, new feature in clang,
179etc), we use `local
180overrides <https://searchfox.org/mozilla-central/rev/501eb4718d73870892d28f31a99b46f4783efaa0/.clang-format>`__.
181
182
183Ignored files & directories
184~~~~~~~~~~~~~~~~~~~~~~~~~~~
185
186We maintain a `list of ignored directories and
187files <https://searchfox.org/mozilla-central/rev/501eb4718d73870892d28f31a99b46f4783efaa0/.clang-format-ignore>`__,
188which is used by ``./mach clang-format``. This is generally only used
189for code broken by clang-format, and third-party code.
190
191
192Ignored code hunks
193~~~~~~~~~~~~~~~~~~
194
195Sections of code may have formatting disabled using comments. If a
196section must not be formatted, the following comments will disable the
197reformat:
198
199::
200
201   // clang-format off
202   my code which should not be reformated
203   // clang-format on
204
205You can find an `example of code not
206formatted <https://searchfox.org/mozilla-central/rev/501eb4718d73870892d28f31a99b46f4783efaa0/xpcom/io/nsEscape.cpp#22>`__.
207
208
209Merging formatted and unformatted code
210--------------------------------------
211
212During the transition to using chromium style enforced by clang-format
213for all code in tree, it will often be necessary to rebase non-formatted
214code onto a formatted tree.
215
216
217Mercurial
218~~~~~~~~~
219
220The ``format-source`` extension, now bundled with
221``version-control-tools``, and installed by ``./mach bootstrap``, may be
222used to seamlessly handle this situation. More details may be found in
223this
224`document <https://docs.google.com/document/d/13AwAsvKMhH0mflDlfatBqn6LmZHiQih76oxM4zfrPl4/edit>`__.
225
226The parent changeset of the reformat has been tagged as
227``PRE_TREEWIDE_CLANG_FORMAT``.
228
229
230Git
231~~~
232
233To perform a rebase onto mozilla-central after the merge, a handy merge
234driver, ``clang-format-merge``, has been written:
235
236.. code:: shell
237
238   $ git clone https://github.com/emilio/clang-format-merge
239   $ /path/to/clang-format-merge/git-wrapper rebase <upstream>
240
241The wrapper should clean up after itself, and the clone may be deleted
242after the rebase is complete.
243
244
245Ignore lists
246------------
247
248To make sure that the blame/annotate features of Mercurial or git aren't
249affected. Two files are maintained to keep track of the reformatting
250commits.
251
252
253With Mercurial
254~~~~~~~~~~~~~~
255
256| The list is stored in
257  `https://searchfox.org/mozilla-central/source/.hg-annotate-ignore-revs </en-US/docs/>`__
258| Commit messages should also contain the string ``# ignore-this-changeset``
259
260The syntax in this file is generated using the following syntax:
261
262::
263
264   $ hg log --template '{node} - {author|person} - {desc|strip|firstline}\n'
265
266With git
267~~~~~~~~
268
269The list is stored in
270`https://searchfox.org/mozilla-central/source/.git-blame-ignore-revs </en-US/docs/>`__
271and contains git revisions for both gecko-dev and the git cinnabar
272repository.
273