|
|
|||
File indexing completed on 2026-05-10 08:37:11
0001 //===--- HeaderIncludes.h - Insert/Delete #includes for C++ code--*- C++-*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 0009 #ifndef LLVM_CLANG_TOOLING_INCLUSIONS_HEADERINCLUDES_H 0010 #define LLVM_CLANG_TOOLING_INCLUSIONS_HEADERINCLUDES_H 0011 0012 #include "clang/Basic/SourceManager.h" 0013 #include "clang/Tooling/Core/Replacement.h" 0014 #include "clang/Tooling/Inclusions/IncludeStyle.h" 0015 #include "llvm/Support/Path.h" 0016 #include "llvm/Support/Regex.h" 0017 #include <list> 0018 #include <optional> 0019 #include <unordered_map> 0020 0021 namespace clang { 0022 namespace tooling { 0023 0024 /// This class manages priorities of C++ #include categories and calculates 0025 /// priorities for headers. 0026 /// FIXME(ioeric): move this class into implementation file when clang-format's 0027 /// include sorting functions are also moved here. 0028 class IncludeCategoryManager { 0029 public: 0030 IncludeCategoryManager(const IncludeStyle &Style, StringRef FileName); 0031 0032 /// Returns the priority of the category which \p IncludeName belongs to. 0033 /// If \p CheckMainHeader is true and \p IncludeName is a main header, returns 0034 /// 0. Otherwise, returns the priority of the matching category or INT_MAX. 0035 /// NOTE: this API is not thread-safe! 0036 int getIncludePriority(StringRef IncludeName, bool CheckMainHeader) const; 0037 int getSortIncludePriority(StringRef IncludeName, bool CheckMainHeader) const; 0038 0039 private: 0040 bool isMainHeader(StringRef IncludeName) const; 0041 0042 const IncludeStyle Style; 0043 bool IsMainFile; 0044 std::string FileName; 0045 SmallVector<llvm::Regex, 4> CategoryRegexs; 0046 }; 0047 0048 enum class IncludeDirective { Include, Import }; 0049 0050 /// Generates replacements for inserting or deleting #include directives in a 0051 /// file. 0052 class HeaderIncludes { 0053 public: 0054 HeaderIncludes(llvm::StringRef FileName, llvm::StringRef Code, 0055 const IncludeStyle &Style); 0056 0057 /// Inserts an #include or #import directive of \p Header into the code. 0058 /// If \p IsAngled is true, \p Header will be quoted with <> in the directive; 0059 /// otherwise, it will be quoted with "". 0060 /// 0061 /// When searching for points to insert new header, this ignores #include's 0062 /// after the #include block(s) in the beginning of a file to avoid inserting 0063 /// headers into code sections where new #include's should not be added by 0064 /// default. These code sections include: 0065 /// - raw string literals (containing #include). 0066 /// - #if blocks. 0067 /// - Special #include's among declarations (e.g. functions). 0068 /// 0069 /// Returns a replacement that inserts the new header into a suitable #include 0070 /// block of the same category. This respects the order of the existing 0071 /// #includes in the block; if the existing #includes are not already sorted, 0072 /// this will simply insert the #include in front of the first #include of the 0073 /// same category in the code that should be sorted after \p IncludeName. If 0074 /// \p IncludeName already exists (with exactly the same spelling), this 0075 /// returns std::nullopt. 0076 std::optional<tooling::Replacement> insert(llvm::StringRef Header, 0077 bool IsAngled, 0078 IncludeDirective Directive) const; 0079 0080 /// Removes all existing #includes and #imports of \p Header quoted with <> if 0081 /// \p IsAngled is true or "" if \p IsAngled is false. 0082 /// This doesn't resolve the header file path; it only deletes #includes and 0083 /// #imports with exactly the same spelling. 0084 tooling::Replacements remove(llvm::StringRef Header, bool IsAngled) const; 0085 0086 // Matches a whole #include directive. 0087 static const llvm::Regex IncludeRegex; 0088 0089 private: 0090 struct Include { 0091 Include(StringRef Name, tooling::Range R, IncludeDirective D) 0092 : Name(Name), R(R), Directive(D) {} 0093 0094 // An include header quoted with either <> or "". 0095 std::string Name; 0096 // The range of the whole line of include directive including any leading 0097 // whitespaces and trailing comment. 0098 tooling::Range R; 0099 // Either #include or #import. 0100 IncludeDirective Directive; 0101 }; 0102 0103 void addExistingInclude(Include IncludeToAdd, unsigned NextLineOffset); 0104 0105 std::string FileName; 0106 std::string Code; 0107 0108 // Map from include name (quotation trimmed) to a list of existing includes 0109 // (in case there are more than one) with the name in the current file. <x> 0110 // and "x" will be treated as the same header when deleting #includes. 0111 // std::list is used for pointers stability (see IncludesByPriority) 0112 llvm::StringMap<std::list<Include>> ExistingIncludes; 0113 0114 /// Map from priorities of #include categories to all #includes in the same 0115 /// category. This is used to find #includes of the same category when 0116 /// inserting new #includes. #includes in the same categories are sorted in 0117 /// in the order they appear in the source file. 0118 /// See comment for "FormatStyle::IncludeCategories" for details about include 0119 /// priorities. 0120 std::unordered_map<int, llvm::SmallVector<const Include *, 8>> 0121 IncludesByPriority; 0122 0123 int FirstIncludeOffset; 0124 // All new headers should be inserted after this offset (e.g. after header 0125 // guards, file comment). 0126 unsigned MinInsertOffset; 0127 // Max insertion offset in the original code. For example, we want to avoid 0128 // inserting new #includes into the actual code section (e.g. after a 0129 // declaration). 0130 unsigned MaxInsertOffset; 0131 // True if we find the main-file header in the Code. 0132 bool MainIncludeFound; 0133 IncludeCategoryManager Categories; 0134 // Record the offset of the end of the last include in each category. 0135 std::unordered_map<int, int> CategoryEndOffsets; 0136 0137 // All possible priorities. 0138 std::set<int> Priorities; 0139 }; 0140 0141 } // namespace tooling 0142 } // namespace clang 0143 0144 #endif // LLVM_CLANG_TOOLING_INCLUSIONS_HEADERINCLUDES_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|