1 //===---------- IncludeInserter.h - clang-tidy ----------------------------===// 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_TOOLS_EXTRA_CLANG_TIDY_INCLUDEINSERTER_H 10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_INCLUDEINSERTER_H 11 12 #include "IncludeSorter.h" 13 #include "clang/Basic/Diagnostic.h" 14 #include "llvm/ADT/StringSet.h" 15 #include <memory> 16 #include <optional> 17 18 namespace clang { 19 class Preprocessor; 20 namespace tidy::utils { 21 22 /// Produces fixes to insert specified includes to source files, if not 23 /// yet present. 24 /// 25 /// ``IncludeInserter`` can be used in clang-tidy checks in the following way: 26 /// \code 27 /// #include "../ClangTidyCheck.h" 28 /// #include "../utils/IncludeInserter.h" 29 /// 30 /// namespace clang { 31 /// namespace tidy { 32 /// 33 /// class MyCheck : public ClangTidyCheck { 34 /// public: 35 /// void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, 36 /// Preprocessor *ModuleExpanderPP) override { 37 /// Inserter.registerPreprocessor(PP); 38 /// } 39 /// 40 /// void registerMatchers(ast_matchers::MatchFinder* Finder) override { ... } 41 /// 42 /// void check( 43 /// const ast_matchers::MatchFinder::MatchResult& Result) override { 44 /// ... 45 /// Inserter.createMainFileIncludeInsertion("path/to/Header.h"); 46 /// ... 47 /// } 48 /// 49 /// private: 50 /// utils::IncludeInserter Inserter{utils::IncludeSorter::IS_Google}; 51 /// }; 52 /// } // namespace tidy 53 /// } // namespace clang 54 /// \endcode 55 class IncludeInserter { 56 public: 57 /// Initializes the IncludeInserter using the IncludeStyle \p Style. 58 /// In most cases the \p Style will be retrieved from the ClangTidyOptions 59 /// using \code 60 /// Options.getLocalOrGlobal("IncludeStyle", <DefaultStyle>) 61 /// \endcode 62 explicit IncludeInserter(IncludeSorter::IncludeStyle Style, 63 bool SelfContainedDiags); 64 65 /// Registers this with the Preprocessor \p PP, must be called before this 66 /// class is used. 67 void registerPreprocessor(Preprocessor *PP); 68 69 /// Creates a \p Header inclusion directive fixit in the File \p FileID. 70 /// When \p Header is enclosed in angle brackets, uses angle brackets in the 71 /// inclusion directive, otherwise uses quotes. 72 /// Returns ``std::nullopt`` on error or if the inclusion directive already 73 /// exists. 74 std::optional<FixItHint> createIncludeInsertion(FileID FileID, 75 llvm::StringRef Header); 76 77 /// Creates a \p Header inclusion directive fixit in the main file. 78 /// When \p Header is enclosed in angle brackets, uses angle brackets in the 79 /// inclusion directive, otherwise uses quotes. 80 /// Returns ``std::nullopt`` on error or if the inclusion directive already 81 /// exists. 82 std::optional<FixItHint> 83 createMainFileIncludeInsertion(llvm::StringRef Header); 84 getStyle()85 IncludeSorter::IncludeStyle getStyle() const { return Style; } 86 87 private: 88 void addInclude(StringRef FileName, bool IsAngled, 89 SourceLocation HashLocation, SourceLocation EndLocation); 90 91 IncludeSorter &getOrCreate(FileID FileID); 92 93 llvm::DenseMap<FileID, std::unique_ptr<IncludeSorter>> IncludeSorterByFile; 94 llvm::DenseMap<FileID, llvm::StringSet<>> InsertedHeaders; 95 const SourceManager *SourceMgr{nullptr}; 96 const IncludeSorter::IncludeStyle Style; 97 const bool SelfContainedDiags; 98 friend class IncludeInserterCallback; 99 }; 100 101 } // namespace tidy::utils 102 } // namespace clang 103 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_INCLUDEINSERTER_H 104