Clang Project

clang_source_code/include/clang/Tooling/Inclusions/IncludeStyle.h
1//===--- IncludeStyle.h - Style of C++ #include directives -------*- C++-*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_CLANG_TOOLING_INCLUSIONS_INCLUDESTYLE_H
10#define LLVM_CLANG_TOOLING_INCLUSIONS_INCLUDESTYLE_H
11
12#include "llvm/Support/YAMLTraits.h"
13#include <string>
14#include <vector>
15
16namespace clang {
17namespace tooling {
18
19/// Style for sorting and grouping C++ #include directives.
20struct IncludeStyle {
21  /// Styles for sorting multiple ``#include`` blocks.
22  enum IncludeBlocksStyle {
23    /// Sort each ``#include`` block separately.
24    /// \code
25    ///    #include "b.h"               into      #include "b.h"
26    ///
27    ///    #include <lib/main.h>                  #include "a.h"
28    ///    #include "a.h"                         #include <lib/main.h>
29    /// \endcode
30    IBS_Preserve,
31    /// Merge multiple ``#include`` blocks together and sort as one.
32    /// \code
33    ///    #include "b.h"               into      #include "a.h"
34    ///                                           #include "b.h"
35    ///    #include <lib/main.h>                  #include <lib/main.h>
36    ///    #include "a.h"
37    /// \endcode
38    IBS_Merge,
39    /// Merge multiple ``#include`` blocks together and sort as one.
40    /// Then split into groups based on category priority. See
41    /// ``IncludeCategories``.
42    /// \code
43    ///    #include "b.h"               into      #include "a.h"
44    ///                                           #include "b.h"
45    ///    #include <lib/main.h>
46    ///    #include "a.h"                         #include <lib/main.h>
47    /// \endcode
48    IBS_Regroup,
49  };
50
51  /// Dependent on the value, multiple ``#include`` blocks can be sorted
52  /// as one and divided based on category.
53  IncludeBlocksStyle IncludeBlocks;
54
55  /// See documentation of ``IncludeCategories``.
56  struct IncludeCategory {
57    /// The regular expression that this category matches.
58    std::string Regex;
59    /// The priority to assign to this category.
60    int Priority;
61    bool operator==(const IncludeCategory &Otherconst {
62      return Regex == Other.Regex && Priority == Other.Priority;
63    }
64  };
65
66  /// Regular expressions denoting the different ``#include`` categories
67  /// used for ordering ``#includes``.
68  ///
69  /// `POSIX extended
70  /// <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html>`_
71  /// regular expressions are supported.
72  ///
73  /// These regular expressions are matched against the filename of an include
74  /// (including the <> or "") in order. The value belonging to the first
75  /// matching regular expression is assigned and ``#includes`` are sorted first
76  /// according to increasing category number and then alphabetically within
77  /// each category.
78  ///
79  /// If none of the regular expressions match, INT_MAX is assigned as
80  /// category. The main header for a source file automatically gets category 0.
81  /// so that it is generally kept at the beginning of the ``#includes``
82  /// (https://llvm.org/docs/CodingStandards.html#include-style). However, you
83  /// can also assign negative priorities if you have certain headers that
84  /// always need to be first.
85  ///
86  /// To configure this in the .clang-format file, use:
87  /// \code{.yaml}
88  ///   IncludeCategories:
89  ///     - Regex:           '^"(llvm|llvm-c|clang|clang-c)/'
90  ///       Priority:        2
91  ///     - Regex:           '^(<|"(gtest|gmock|isl|json)/)'
92  ///       Priority:        3
93  ///     - Regex:           '<[[:alnum:].]+>'
94  ///       Priority:        4
95  ///     - Regex:           '.*'
96  ///       Priority:        1
97  /// \endcode
98  std::vector<IncludeCategoryIncludeCategories;
99
100  /// Specify a regular expression of suffixes that are allowed in the
101  /// file-to-main-include mapping.
102  ///
103  /// When guessing whether a #include is the "main" include (to assign
104  /// category 0, see above), use this regex of allowed suffixes to the header
105  /// stem. A partial match is done, so that:
106  /// - "" means "arbitrary suffix"
107  /// - "$" means "no suffix"
108  ///
109  /// For example, if configured to "(_test)?$", then a header a.h would be seen
110  /// as the "main" include in both a.cc and a_test.cc.
111  std::string IncludeIsMainRegex;
112};
113
114// namespace tooling
115// namespace clang
116
117LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::IncludeStyle::IncludeCategory)
118
119namespace llvm {
120namespace yaml {
121
122template <>
123struct MappingTraits<clang::tooling::IncludeStyle::IncludeCategory> {
124  static void mapping(IO &IO,
125                      clang::tooling::IncludeStyle::IncludeCategory &Category);
126};
127
128template <>
129struct ScalarEnumerationTraits<
130    clang::tooling::IncludeStyle::IncludeBlocksStyle> {
131  static void
132  enumeration(IO &IO, clang::tooling::IncludeStyle::IncludeBlocksStyle &Value);
133};
134
135// namespace yaml
136// namespace llvm
137
138#endif // LLVM_CLANG_TOOLING_INCLUSIONS_INCLUDESTYLE_H
139
clang::tooling::IncludeStyle::IncludeBlocksStyle
clang::tooling::IncludeStyle::IncludeBlocks
clang::tooling::IncludeStyle::IncludeCategory
clang::tooling::IncludeStyle::IncludeCategory::Regex
clang::tooling::IncludeStyle::IncludeCategory::Priority
clang::tooling::IncludeStyle::IncludeCategories
clang::tooling::IncludeStyle::IncludeIsMainRegex