- //===--- HeaderIncludes.h - Insert/Delete #includes for C++ code--*- C++-*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_CLANG_TOOLING_INCLUSIONS_HEADERINCLUDES_H 
- #define LLVM_CLANG_TOOLING_INCLUSIONS_HEADERINCLUDES_H 
-   
- #include "clang/Basic/SourceManager.h" 
- #include "clang/Tooling/Core/Replacement.h" 
- #include "clang/Tooling/Inclusions/IncludeStyle.h" 
- #include "llvm/Support/Path.h" 
- #include "llvm/Support/Regex.h" 
- #include <list> 
- #include <optional> 
- #include <unordered_map> 
-   
- namespace clang { 
- namespace tooling { 
-   
- /// This class manages priorities of C++ #include categories and calculates 
- /// priorities for headers. 
- /// FIXME(ioeric): move this class into implementation file when clang-format's 
- /// include sorting functions are also moved here. 
- class IncludeCategoryManager { 
- public: 
-   IncludeCategoryManager(const IncludeStyle &Style, StringRef FileName); 
-   
-   /// Returns the priority of the category which \p IncludeName belongs to. 
-   /// If \p CheckMainHeader is true and \p IncludeName is a main header, returns 
-   /// 0. Otherwise, returns the priority of the matching category or INT_MAX. 
-   /// NOTE: this API is not thread-safe! 
-   int getIncludePriority(StringRef IncludeName, bool CheckMainHeader) const; 
-   int getSortIncludePriority(StringRef IncludeName, bool CheckMainHeader) const; 
-   
- private: 
-   bool isMainHeader(StringRef IncludeName) const; 
-   
-   const IncludeStyle Style; 
-   bool IsMainFile; 
-   std::string FileName; 
-   SmallVector<llvm::Regex, 4> CategoryRegexs; 
- }; 
-   
- enum class IncludeDirective { Include, Import }; 
-   
- /// Generates replacements for inserting or deleting #include directives in a 
- /// file. 
- class HeaderIncludes { 
- public: 
-   HeaderIncludes(llvm::StringRef FileName, llvm::StringRef Code, 
-                  const IncludeStyle &Style); 
-   
-   /// Inserts an #include or #import directive of \p Header into the code. 
-   /// If \p IsAngled is true, \p Header will be quoted with <> in the directive; 
-   /// otherwise, it will be quoted with "". 
-   /// 
-   /// When searching for points to insert new header, this ignores #include's 
-   /// after the #include block(s) in the beginning of a file to avoid inserting 
-   /// headers into code sections where new #include's should not be added by 
-   /// default. These code sections include: 
-   ///   - raw string literals (containing #include). 
-   ///   - #if blocks. 
-   ///   - Special #include's among declarations (e.g. functions). 
-   /// 
-   /// Returns a replacement that inserts the new header into a suitable #include 
-   /// block of the same category. This respects the order of the existing 
-   /// #includes in the block; if the existing #includes are not already sorted, 
-   /// this will simply insert the #include in front of the first #include of the 
-   /// same category in the code that should be sorted after \p IncludeName. If 
-   /// \p IncludeName already exists (with exactly the same spelling), this 
-   /// returns std::nullopt. 
-   std::optional<tooling::Replacement> insert(llvm::StringRef Header, 
-                                              bool IsAngled, 
-                                              IncludeDirective Directive) const; 
-   
-   /// Removes all existing #includes and #imports of \p Header quoted with <> if 
-   /// \p IsAngled is true or "" if \p IsAngled is false. 
-   /// This doesn't resolve the header file path; it only deletes #includes and 
-   /// #imports with exactly the same spelling. 
-   tooling::Replacements remove(llvm::StringRef Header, bool IsAngled) const; 
-   
-   // Matches a whole #include directive. 
-   static const llvm::Regex IncludeRegex; 
-   
- private: 
-   struct Include { 
-     Include(StringRef Name, tooling::Range R, IncludeDirective D) 
-         : Name(Name), R(R), Directive(D) {} 
-   
-     // An include header quoted with either <> or "". 
-     std::string Name; 
-     // The range of the whole line of include directive including any leading 
-     // whitespaces and trailing comment. 
-     tooling::Range R; 
-     // Either #include or #import. 
-     IncludeDirective Directive; 
-   }; 
-   
-   void addExistingInclude(Include IncludeToAdd, unsigned NextLineOffset); 
-   
-   std::string FileName; 
-   std::string Code; 
-   
-   // Map from include name (quotation trimmed) to a list of existing includes 
-   // (in case there are more than one) with the name in the current file. <x> 
-   // and "x" will be treated as the same header when deleting #includes. 
-   // std::list is used for pointers stability (see IncludesByPriority) 
-   llvm::StringMap<std::list<Include>> ExistingIncludes; 
-   
-   /// Map from priorities of #include categories to all #includes in the same 
-   /// category. This is used to find #includes of the same category when 
-   /// inserting new #includes. #includes in the same categories are sorted in 
-   /// in the order they appear in the source file. 
-   /// See comment for "FormatStyle::IncludeCategories" for details about include 
-   /// priorities. 
-   std::unordered_map<int, llvm::SmallVector<const Include *, 8>> 
-       IncludesByPriority; 
-   
-   int FirstIncludeOffset; 
-   // All new headers should be inserted after this offset (e.g. after header 
-   // guards, file comment). 
-   unsigned MinInsertOffset; 
-   // Max insertion offset in the original code. For example, we want to avoid 
-   // inserting new #includes into the actual code section (e.g. after a 
-   // declaration). 
-   unsigned MaxInsertOffset; 
-   IncludeCategoryManager Categories; 
-   // Record the offset of the end of the last include in each category. 
-   std::unordered_map<int, int> CategoryEndOffsets; 
-   
-   // All possible priorities. 
-   std::set<int> Priorities; 
- }; 
-   
- } // namespace tooling 
- } // namespace clang 
-   
- #endif // LLVM_CLANG_TOOLING_INCLUSIONS_HEADERINCLUDES_H 
-