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