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
|
#pragma once
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
//===--- IncludeStyle.h - Style of C++ #include directives -------*- C++-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLING_INCLUSIONS_INCLUDESTYLE_H
#define LLVM_CLANG_TOOLING_INCLUSIONS_INCLUDESTYLE_H
#include "llvm/Support/YAMLTraits.h"
#include <string>
#include <vector>
namespace clang {
namespace tooling {
/// Style for sorting and grouping C++ #include directives.
struct IncludeStyle {
/// Styles for sorting multiple ``#include`` blocks.
enum IncludeBlocksStyle {
/// Sort each ``#include`` block separately.
/// \code
/// #include "b.h" into #include "b.h"
///
/// #include <lib/main.h> #include "a.h"
/// #include "a.h" #include <lib/main.h>
/// \endcode
IBS_Preserve,
/// Merge multiple ``#include`` blocks together and sort as one.
/// \code
/// #include "b.h" into #include "a.h"
/// #include "b.h"
/// #include <lib/main.h> #include <lib/main.h>
/// #include "a.h"
/// \endcode
IBS_Merge,
/// Merge multiple ``#include`` blocks together and sort as one.
/// Then split into groups based on category priority. See
/// ``IncludeCategories``.
/// \code
/// #include "b.h" into #include "a.h"
/// #include "b.h"
/// #include <lib/main.h>
/// #include "a.h" #include <lib/main.h>
/// \endcode
IBS_Regroup,
};
/// Dependent on the value, multiple ``#include`` blocks can be sorted
/// as one and divided based on category.
/// \version 6
IncludeBlocksStyle IncludeBlocks;
/// See documentation of ``IncludeCategories``.
struct IncludeCategory {
/// The regular expression that this category matches.
std::string Regex;
/// The priority to assign to this category.
int Priority;
/// The custom priority to sort before grouping.
int SortPriority;
/// If the regular expression is case sensitive.
bool RegexIsCaseSensitive;
bool operator==(const IncludeCategory &Other) const {
return Regex == Other.Regex && Priority == Other.Priority &&
RegexIsCaseSensitive == Other.RegexIsCaseSensitive;
}
};
/// Regular expressions denoting the different ``#include`` categories
/// used for ordering ``#includes``.
///
/// `POSIX extended
/// <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html>`_
/// regular expressions are supported.
///
/// These regular expressions are matched against the filename of an include
/// (including the <> or "") in order. The value belonging to the first
/// matching regular expression is assigned and ``#includes`` are sorted first
/// according to increasing category number and then alphabetically within
/// each category.
///
/// If none of the regular expressions match, INT_MAX is assigned as
/// category. The main header for a source file automatically gets category 0.
/// so that it is generally kept at the beginning of the ``#includes``
/// (https://llvm.org/docs/CodingStandards.html#include-style). However, you
/// can also assign negative priorities if you have certain headers that
/// always need to be first.
///
/// There is a third and optional field ``SortPriority`` which can used while
/// ``IncludeBlocks = IBS_Regroup`` to define the priority in which
/// ``#includes`` should be ordered. The value of ``Priority`` defines the
/// order of ``#include blocks`` and also allows the grouping of ``#includes``
/// of different priority. ``SortPriority`` is set to the value of
/// ``Priority`` as default if it is not assigned.
///
/// Each regular expression can be marked as case sensitive with the field
/// ``CaseSensitive``, per default it is not.
///
/// To configure this in the .clang-format file, use:
/// \code{.yaml}
/// IncludeCategories:
/// - Regex: '^"(llvm|llvm-c|clang|clang-c)/'
/// Priority: 2
/// SortPriority: 2
/// CaseSensitive: true
/// - Regex: '^((<|")(gtest|gmock|isl|json)/)'
/// Priority: 3
/// - Regex: '<[[:alnum:].]+>'
/// Priority: 4
/// - Regex: '.*'
/// Priority: 1
/// SortPriority: 0
/// \endcode
/// \version 3.8
std::vector<IncludeCategory> IncludeCategories;
/// Specify a regular expression of suffixes that are allowed in the
/// file-to-main-include mapping.
///
/// When guessing whether a #include is the "main" include (to assign
/// category 0, see above), use this regex of allowed suffixes to the header
/// stem. A partial match is done, so that:
/// - "" means "arbitrary suffix"
/// - "$" means "no suffix"
///
/// For example, if configured to "(_test)?$", then a header a.h would be seen
/// as the "main" include in both a.cc and a_test.cc.
/// \version 3.9
std::string IncludeIsMainRegex;
/// Specify a regular expression for files being formatted
/// that are allowed to be considered "main" in the
/// file-to-main-include mapping.
///
/// By default, clang-format considers files as "main" only when they end
/// with: ``.c``, ``.cc``, ``.cpp``, ``.c++``, ``.cxx``, ``.m`` or ``.mm``
/// extensions.
/// For these files a guessing of "main" include takes place
/// (to assign category 0, see above). This config option allows for
/// additional suffixes and extensions for files to be considered as "main".
///
/// For example, if this option is configured to ``(Impl\.hpp)$``,
/// then a file ``ClassImpl.hpp`` is considered "main" (in addition to
/// ``Class.c``, ``Class.cc``, ``Class.cpp`` and so on) and "main
/// include file" logic will be executed (with *IncludeIsMainRegex* setting
/// also being respected in later phase). Without this option set,
/// ``ClassImpl.hpp`` would not have the main include file put on top
/// before any other include.
/// \version 10
std::string IncludeIsMainSourceRegex;
};
} // namespace tooling
} // namespace clang
LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::IncludeStyle::IncludeCategory)
namespace llvm {
namespace yaml {
template <>
struct MappingTraits<clang::tooling::IncludeStyle::IncludeCategory> {
static void mapping(IO &IO,
clang::tooling::IncludeStyle::IncludeCategory &Category);
};
template <>
struct ScalarEnumerationTraits<
clang::tooling::IncludeStyle::IncludeBlocksStyle> {
static void
enumeration(IO &IO, clang::tooling::IncludeStyle::IncludeBlocksStyle &Value);
};
} // namespace yaml
} // namespace llvm
#endif // LLVM_CLANG_TOOLING_INCLUSIONS_INCLUDESTYLE_H
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
|