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 16 namespace clang { 17 namespace tooling { 18 19 /// Style for sorting and grouping C++ #include directives. 20 struct 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 /// \version 6 54 IncludeBlocksStyle IncludeBlocks; 55 56 /// See documentation of ``IncludeCategories``. 57 struct IncludeCategory { 58 /// The regular expression that this category matches. 59 std::string Regex; 60 /// The priority to assign to this category. 61 int Priority; 62 /// The custom priority to sort before grouping. 63 int SortPriority; 64 /// If the regular expression is case sensitive. 65 bool RegexIsCaseSensitive; 66 bool operator==(const IncludeCategory &Other) const { 67 return Regex == Other.Regex && Priority == Other.Priority && 68 RegexIsCaseSensitive == Other.RegexIsCaseSensitive; 69 } 70 }; 71 72 /// Regular expressions denoting the different ``#include`` categories 73 /// used for ordering ``#includes``. 74 /// 75 /// `POSIX extended 76 /// <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html>`_ 77 /// regular expressions are supported. 78 /// 79 /// These regular expressions are matched against the filename of an include 80 /// (including the <> or "") in order. The value belonging to the first 81 /// matching regular expression is assigned and ``#includes`` are sorted first 82 /// according to increasing category number and then alphabetically within 83 /// each category. 84 /// 85 /// If none of the regular expressions match, INT_MAX is assigned as 86 /// category. The main header for a source file automatically gets category 0. 87 /// so that it is generally kept at the beginning of the ``#includes`` 88 /// (https://llvm.org/docs/CodingStandards.html#include-style). However, you 89 /// can also assign negative priorities if you have certain headers that 90 /// always need to be first. 91 /// 92 /// There is a third and optional field ``SortPriority`` which can used while 93 /// ``IncludeBlocks = IBS_Regroup`` to define the priority in which 94 /// ``#includes`` should be ordered. The value of ``Priority`` defines the 95 /// order of ``#include blocks`` and also allows the grouping of ``#includes`` 96 /// of different priority. ``SortPriority`` is set to the value of 97 /// ``Priority`` as default if it is not assigned. 98 /// 99 /// Each regular expression can be marked as case sensitive with the field 100 /// ``CaseSensitive``, per default it is not. 101 /// 102 /// To configure this in the .clang-format file, use: 103 /// \code{.yaml} 104 /// IncludeCategories: 105 /// - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 106 /// Priority: 2 107 /// SortPriority: 2 108 /// CaseSensitive: true 109 /// - Regex: '^((<|")(gtest|gmock|isl|json)/)' 110 /// Priority: 3 111 /// - Regex: '<[[:alnum:].]+>' 112 /// Priority: 4 113 /// - Regex: '.*' 114 /// Priority: 1 115 /// SortPriority: 0 116 /// \endcode 117 /// \version 3.8 118 std::vector<IncludeCategory> IncludeCategories; 119 120 /// Specify a regular expression of suffixes that are allowed in the 121 /// file-to-main-include mapping. 122 /// 123 /// When guessing whether a #include is the "main" include (to assign 124 /// category 0, see above), use this regex of allowed suffixes to the header 125 /// stem. A partial match is done, so that: 126 /// - "" means "arbitrary suffix" 127 /// - "$" means "no suffix" 128 /// 129 /// For example, if configured to "(_test)?$", then a header a.h would be seen 130 /// as the "main" include in both a.cc and a_test.cc. 131 /// \version 3.9 132 std::string IncludeIsMainRegex; 133 134 /// Specify a regular expression for files being formatted 135 /// that are allowed to be considered "main" in the 136 /// file-to-main-include mapping. 137 /// 138 /// By default, clang-format considers files as "main" only when they end 139 /// with: ``.c``, ``.cc``, ``.cpp``, ``.c++``, ``.cxx``, ``.m`` or ``.mm`` 140 /// extensions. 141 /// For these files a guessing of "main" include takes place 142 /// (to assign category 0, see above). This config option allows for 143 /// additional suffixes and extensions for files to be considered as "main". 144 /// 145 /// For example, if this option is configured to ``(Impl\.hpp)$``, 146 /// then a file ``ClassImpl.hpp`` is considered "main" (in addition to 147 /// ``Class.c``, ``Class.cc``, ``Class.cpp`` and so on) and "main 148 /// include file" logic will be executed (with *IncludeIsMainRegex* setting 149 /// also being respected in later phase). Without this option set, 150 /// ``ClassImpl.hpp`` would not have the main include file put on top 151 /// before any other include. 152 /// \version 10 153 std::string IncludeIsMainSourceRegex; 154 }; 155 156 } // namespace tooling 157 } // namespace clang 158 159 LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::IncludeStyle::IncludeCategory) 160 161 namespace llvm { 162 namespace yaml { 163 164 template <> 165 struct MappingTraits<clang::tooling::IncludeStyle::IncludeCategory> { 166 static void mapping(IO &IO, 167 clang::tooling::IncludeStyle::IncludeCategory &Category); 168 }; 169 170 template <> 171 struct ScalarEnumerationTraits< 172 clang::tooling::IncludeStyle::IncludeBlocksStyle> { 173 static void 174 enumeration(IO &IO, clang::tooling::IncludeStyle::IncludeBlocksStyle &Value); 175 }; 176 177 } // namespace yaml 178 } // namespace llvm 179 180 #endif // LLVM_CLANG_TOOLING_INCLUSIONS_INCLUDESTYLE_H 181