1336815Sdim//===--- IncludeStyle.h - Style of C++ #include directives -------*- C++-*-===// 2336815Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6336815Sdim// 7336815Sdim//===----------------------------------------------------------------------===// 8336815Sdim 9336815Sdim#ifndef LLVM_CLANG_TOOLING_INCLUSIONS_INCLUDESTYLE_H 10336815Sdim#define LLVM_CLANG_TOOLING_INCLUSIONS_INCLUDESTYLE_H 11336815Sdim 12336815Sdim#include "llvm/Support/YAMLTraits.h" 13336815Sdim#include <string> 14336815Sdim#include <vector> 15336815Sdim 16336815Sdimnamespace clang { 17336815Sdimnamespace tooling { 18336815Sdim 19336815Sdim/// Style for sorting and grouping C++ #include directives. 20336815Sdimstruct IncludeStyle { 21336815Sdim /// Styles for sorting multiple ``#include`` blocks. 22336815Sdim enum IncludeBlocksStyle { 23336815Sdim /// Sort each ``#include`` block separately. 24336815Sdim /// \code 25336815Sdim /// #include "b.h" into #include "b.h" 26336815Sdim /// 27336815Sdim /// #include <lib/main.h> #include "a.h" 28336815Sdim /// #include "a.h" #include <lib/main.h> 29336815Sdim /// \endcode 30336815Sdim IBS_Preserve, 31336815Sdim /// Merge multiple ``#include`` blocks together and sort as one. 32336815Sdim /// \code 33336815Sdim /// #include "b.h" into #include "a.h" 34336815Sdim /// #include "b.h" 35336815Sdim /// #include <lib/main.h> #include <lib/main.h> 36336815Sdim /// #include "a.h" 37336815Sdim /// \endcode 38336815Sdim IBS_Merge, 39336815Sdim /// Merge multiple ``#include`` blocks together and sort as one. 40336815Sdim /// Then split into groups based on category priority. See 41336815Sdim /// ``IncludeCategories``. 42336815Sdim /// \code 43336815Sdim /// #include "b.h" into #include "a.h" 44336815Sdim /// #include "b.h" 45336815Sdim /// #include <lib/main.h> 46336815Sdim /// #include "a.h" #include <lib/main.h> 47336815Sdim /// \endcode 48336815Sdim IBS_Regroup, 49336815Sdim }; 50336815Sdim 51336815Sdim /// Dependent on the value, multiple ``#include`` blocks can be sorted 52336815Sdim /// as one and divided based on category. 53336815Sdim IncludeBlocksStyle IncludeBlocks; 54336815Sdim 55336815Sdim /// See documentation of ``IncludeCategories``. 56336815Sdim struct IncludeCategory { 57336815Sdim /// The regular expression that this category matches. 58336815Sdim std::string Regex; 59336815Sdim /// The priority to assign to this category. 60336815Sdim int Priority; 61360784Sdim /// The custom priority to sort before grouping. 62360784Sdim int SortPriority; 63336815Sdim bool operator==(const IncludeCategory &Other) const { 64336815Sdim return Regex == Other.Regex && Priority == Other.Priority; 65336815Sdim } 66336815Sdim }; 67336815Sdim 68336815Sdim /// Regular expressions denoting the different ``#include`` categories 69336815Sdim /// used for ordering ``#includes``. 70336815Sdim /// 71336815Sdim /// `POSIX extended 72353358Sdim /// <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html>`_ 73336815Sdim /// regular expressions are supported. 74336815Sdim /// 75336815Sdim /// These regular expressions are matched against the filename of an include 76336815Sdim /// (including the <> or "") in order. The value belonging to the first 77336815Sdim /// matching regular expression is assigned and ``#includes`` are sorted first 78336815Sdim /// according to increasing category number and then alphabetically within 79336815Sdim /// each category. 80336815Sdim /// 81336815Sdim /// If none of the regular expressions match, INT_MAX is assigned as 82336815Sdim /// category. The main header for a source file automatically gets category 0. 83336815Sdim /// so that it is generally kept at the beginning of the ``#includes`` 84353358Sdim /// (https://llvm.org/docs/CodingStandards.html#include-style). However, you 85336815Sdim /// can also assign negative priorities if you have certain headers that 86336815Sdim /// always need to be first. 87360784Sdim /// 88360784Sdim /// There is a third and optional field ``SortPriority`` which can used while 89360784Sdim /// ``IncludeBloks = IBS_Regroup`` to define the priority in which ``#includes`` 90360784Sdim /// should be ordered, and value of ``Priority`` defines the order of 91360784Sdim /// ``#include blocks`` and also enables to group ``#includes`` of different 92360784Sdim /// priority for order.``SortPriority`` is set to the value of ``Priority`` 93360784Sdim /// as default if it is not assigned. 94336815Sdim /// 95336815Sdim /// To configure this in the .clang-format file, use: 96336815Sdim /// \code{.yaml} 97336815Sdim /// IncludeCategories: 98336815Sdim /// - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 99336815Sdim /// Priority: 2 100360784Sdim /// SortPriority: 2 101336815Sdim /// - Regex: '^(<|"(gtest|gmock|isl|json)/)' 102336815Sdim /// Priority: 3 103336815Sdim /// - Regex: '<[[:alnum:].]+>' 104336815Sdim /// Priority: 4 105336815Sdim /// - Regex: '.*' 106336815Sdim /// Priority: 1 107360784Sdim /// SortPriority: 0 108336815Sdim /// \endcode 109336815Sdim std::vector<IncludeCategory> IncludeCategories; 110336815Sdim 111336815Sdim /// Specify a regular expression of suffixes that are allowed in the 112336815Sdim /// file-to-main-include mapping. 113336815Sdim /// 114336815Sdim /// When guessing whether a #include is the "main" include (to assign 115336815Sdim /// category 0, see above), use this regex of allowed suffixes to the header 116336815Sdim /// stem. A partial match is done, so that: 117336815Sdim /// - "" means "arbitrary suffix" 118336815Sdim /// - "$" means "no suffix" 119336815Sdim /// 120336815Sdim /// For example, if configured to "(_test)?$", then a header a.h would be seen 121336815Sdim /// as the "main" include in both a.cc and a_test.cc. 122336815Sdim std::string IncludeIsMainRegex; 123360784Sdim 124360784Sdim /// Specify a regular expression for files being formatted 125360784Sdim /// that are allowed to be considered "main" in the 126360784Sdim /// file-to-main-include mapping. 127360784Sdim /// 128360784Sdim /// By default, clang-format considers files as "main" only when they end 129360784Sdim /// with: ``.c``, ``.cc``, ``.cpp``, ``.c++``, ``.cxx``, ``.m`` or ``.mm`` 130360784Sdim /// extensions. 131360784Sdim /// For these files a guessing of "main" include takes place 132360784Sdim /// (to assign category 0, see above). This config option allows for 133360784Sdim /// additional suffixes and extensions for files to be considered as "main". 134360784Sdim /// 135360784Sdim /// For example, if this option is configured to ``(Impl\.hpp)$``, 136360784Sdim /// then a file ``ClassImpl.hpp`` is considered "main" (in addition to 137360784Sdim /// ``Class.c``, ``Class.cc``, ``Class.cpp`` and so on) and "main 138360784Sdim /// include file" logic will be executed (with *IncludeIsMainRegex* setting 139360784Sdim /// also being respected in later phase). Without this option set, 140360784Sdim /// ``ClassImpl.hpp`` would not have the main include file put on top 141360784Sdim /// before any other include. 142360784Sdim std::string IncludeIsMainSourceRegex; 143336815Sdim}; 144336815Sdim 145336815Sdim} // namespace tooling 146336815Sdim} // namespace clang 147336815Sdim 148336815SdimLLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::IncludeStyle::IncludeCategory) 149336815Sdim 150336815Sdimnamespace llvm { 151336815Sdimnamespace yaml { 152336815Sdim 153336815Sdimtemplate <> 154336815Sdimstruct MappingTraits<clang::tooling::IncludeStyle::IncludeCategory> { 155336815Sdim static void mapping(IO &IO, 156336815Sdim clang::tooling::IncludeStyle::IncludeCategory &Category); 157336815Sdim}; 158336815Sdim 159336815Sdimtemplate <> 160336815Sdimstruct ScalarEnumerationTraits< 161336815Sdim clang::tooling::IncludeStyle::IncludeBlocksStyle> { 162336815Sdim static void 163336815Sdim enumeration(IO &IO, clang::tooling::IncludeStyle::IncludeBlocksStyle &Value); 164336815Sdim}; 165336815Sdim 166336815Sdim} // namespace yaml 167336815Sdim} // namespace llvm 168336815Sdim 169336815Sdim#endif // LLVM_CLANG_TOOLING_INCLUSIONS_INCLUDESTYLE_H 170