[clang-tidy] Add option to ignore macros in readability-function-cognitive-complexity...
[lldb.git] / clang-tools-extra / docs / clang-tidy / checks / readability-function-cognitive-complexity.rst
1 .. title:: clang-tidy - readability-function-cognitive-complexity
2
3 readability-function-cognitive-complexity
4 =========================================
5
6 Checks function Cognitive Complexity metric.
7
8 The metric is implemented as per the `COGNITIVE COMPLEXITY by SonarSource
9 <https://www.sonarsource.com/docs/CognitiveComplexity.pdf>`_ specification
10 version 1.2 (19 April 2017).
11
12 Options
13 -------
14
15 .. option:: Threshold
16
17    Flag functions with Cognitive Complexity exceeding this number.
18    The default is `25`.
19
20 .. option:: DescribeBasicIncrements
21
22    If set to `true`, then for each function exceeding the complexity threshold
23    the check will issue additional diagnostics on every piece of code (loop,
24    `if` statement, etc.) which contributes to that complexity. See also the
25    examples below. Default is `true`.
26
27 .. option:: IgnoreMacros
28
29    If set to `true`, the check will ignore code inside macros. Note, that also
30    any macro arguments are ignored, even if they should count to the complexity.
31    As this might change in the future, this option isn't guarantueed to be
32    forward-compatible. Default is `false`.
33
34 Building blocks
35 ---------------
36
37 There are three basic building blocks of a Cognitive Complexity metric:
38
39 Increment
40 ^^^^^^^^^
41
42 The following structures increase the function's Cognitive Complexity metric
43 (by `1`):
44
45 * Conditional operators:
46
47    - ``if()``
48    - ``else if()``
49    - ``else``
50    - ``cond ? true : false``
51
52 * ``switch()``
53 * Loops:
54
55    - ``for()``
56    - C++11 range-based ``for()``
57    - ``while()``
58    - ``do while()``
59
60 * ``catch ()``
61 * ``goto LABEL``, ``goto *(&&LABEL))``,
62 * sequences of binary logical operators:
63
64    - ``boolean1 || boolean2``
65    - ``boolean1 && boolean2``
66
67 Nesting level
68 ^^^^^^^^^^^^^
69
70 While by itself the nesting level not change the function's Cognitive Complexity
71 metric, it is tracked, and is used by the next, third building block.
72 The following structures increase the nesting level (by `1`):
73
74 * Conditional operators:
75
76    - ``if()``
77    - ``else if()``
78    - ``else``
79    - ``cond ? true : false``
80
81 * ``switch()``
82 * Loops:
83
84    - ``for()``
85    - C++11 range-based ``for()``
86    - ``while()``
87    - ``do while()``
88
89 * ``catch ()``
90 * Nested functions:
91
92    - C++11 Lambda
93    - Nested ``class``
94    - Nested ``struct``
95 * GNU statement expression
96 * Apple Block Declaration
97
98 Nesting increment
99 ^^^^^^^^^^^^^^^^^
100
101 This is where the previous basic building block, `Nesting level`_, matters.
102 The following structures increase the function's Cognitive Complexity metric by
103 the current `Nesting level`_:
104
105 * Conditional operators:
106
107    - ``if()``
108    - ``cond ? true : false``
109
110 * ``switch()``
111 * Loops:
112
113    - ``for()``
114    - C++11 range-based ``for()``
115    - ``while()``
116    - ``do while()``
117
118 * ``catch ()``
119
120 Examples
121 --------
122
123 The simplest case. This function has Cognitive Complexity of `0`.
124
125 .. code-block:: c++
126
127   void function0() {}
128
129 Slightly better example. This function has Cognitive Complexity of `1`.
130
131 .. code-block:: c++
132
133   int function1(bool var) {
134     if(var) // +1, nesting level +1
135       return 42;
136     return 0;
137   }
138
139 Full example. This function has Cognitive Complexity of `3`.
140
141 .. code-block:: c++
142
143   int function3(bool var1, bool var2) {
144     if(var1) { // +1, nesting level +1
145       if(var2)  // +2 (1 + current nesting level of 1), nesting level +1
146         return 42;
147     }
148
149     return 0;
150   }
151
152 In the last example, the check will flag `function3` if the option Threshold is
153 set to `2` or smaller. If the option DescribeBasicIncrements is set to `true`,
154 it will additionally flag the two `if` statements with the amounts by which they
155 increase to the complexity of the function and the current nesting level.
156
157 Limitations
158 -----------
159
160 The metric is implemented with two notable exceptions:
161    * `preprocessor conditionals` (``#ifdef``, ``#if``, ``#elif``, ``#else``,
162      ``#endif``) are not accounted for.
163    * `each method in a recursion cycle` is not accounted for. It can't be fully
164      implemented, because cross-translational-unit analysis would be needed,
165      which is currently not possible in clang-tidy.