b14c684f57f5c064f5779a22c6ac563dfe16983f
[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 Building blocks
28 ---------------
29
30 There are three basic building blocks of a Cognitive Complexity metric:
31
32 Increment
33 ^^^^^^^^^
34
35 The following structures increase the function's Cognitive Complexity metric
36 (by `1`):
37
38 * Conditional operators:
39
40    - ``if()``
41    - ``else if()``
42    - ``else``
43    - ``cond ? true : false``
44
45 * ``switch()``
46 * Loops:
47
48    - ``for()``
49    - C++11 range-based ``for()``
50    - ``while()``
51    - ``do while()``
52
53 * ``catch ()``
54 * ``goto LABEL``, ``goto *(&&LABEL))``,
55 * sequences of binary logical operators:
56
57    - ``boolean1 || boolean2``
58    - ``boolean1 && boolean2``
59
60 Nesting level
61 ^^^^^^^^^^^^^
62
63 While by itself the nesting level not change the function's Cognitive Complexity
64 metric, it is tracked, and is used by the next, third building block.
65 The following structures increase the nesting level (by `1`):
66
67 * Conditional operators:
68
69    - ``if()``
70    - ``else if()``
71    - ``else``
72    - ``cond ? true : false``
73
74 * ``switch()``
75 * Loops:
76
77    - ``for()``
78    - C++11 range-based ``for()``
79    - ``while()``
80    - ``do while()``
81
82 * ``catch ()``
83 * Nested functions:
84
85    - C++11 Lambda
86    - Nested ``class``
87    - Nested ``struct``
88 * GNU statement expression
89 * Apple Block Declaration
90
91 Nesting increment
92 ^^^^^^^^^^^^^^^^^
93
94 This is where the previous basic building block, `Nesting level`_, matters.
95 The following structures increase the function's Cognitive Complexity metric by
96 the current `Nesting level`_:
97
98 * Conditional operators:
99
100    - ``if()``
101    - ``cond ? true : false``
102
103 * ``switch()``
104 * Loops:
105
106    - ``for()``
107    - C++11 range-based ``for()``
108    - ``while()``
109    - ``do while()``
110
111 * ``catch ()``
112
113 Examples
114 --------
115
116 The simplest case. This function has Cognitive Complexity of `0`.
117
118 .. code-block:: c++
119
120   void function0() {}
121
122 Slightly better example. This function has Cognitive Complexity of `1`.
123
124 .. code-block:: c++
125
126   int function1(bool var) {
127     if(var) // +1, nesting level +1
128       return 42;
129     return 0;
130   }
131
132 Full example. This function has Cognitive Complexity of `3`.
133
134 .. code-block:: c++
135
136   int function3(bool var1, bool var2) {
137     if(var1) { // +1, nesting level +1
138       if(var2)  // +2 (1 + current nesting level of 1), nesting level +1
139         return 42;
140     }
141
142     return 0;
143   }
144
145 In the last example, the check will flag `function3` if the option Threshold is
146 set to `2` or smaller. If the option DescribeBasicIncrements is set to `true`,
147 it will additionally flag the two `if` statements with the amounts by which they
148 increase to the complexity of the function and the current nesting level.
149
150 Limitations
151 -----------
152
153 The metric is implemented with two notable exceptions:
154    * `preprocessor conditionals` (``#ifdef``, ``#if``, ``#elif``, ``#else``,
155      ``#endif``) are not accounted for.
156    * `each method in a recursion cycle` is not accounted for. It can't be fully
157      implemented, because cross-translational-unit analysis would be needed,
158      which is currently not possible in clang-tidy.