104 lines · c
1//===----------------------------------------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_INCLUDEINSERTER_H10#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_INCLUDEINSERTER_H11 12#include "IncludeSorter.h"13#include "clang/Basic/Diagnostic.h"14#include "llvm/ADT/StringSet.h"15#include <memory>16#include <optional>17 18namespace clang {19class Preprocessor;20namespace tidy::utils {21 22/// Produces fixes to insert specified includes to source files, if not23/// yet present.24///25/// ``IncludeInserter`` can be used in clang-tidy checks in the following way:26/// \code27/// #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 tidy53/// } // namespace clang54/// \endcode55class IncludeInserter {56public:57 /// Initializes the IncludeInserter using the IncludeStyle \p Style.58 /// In most cases the \p Style will be retrieved from the ClangTidyOptions59 /// using \code60 /// Options.getLocalOrGlobal("IncludeStyle", <DefaultStyle>)61 /// \endcode62 explicit IncludeInserter(IncludeSorter::IncludeStyle Style,63 bool SelfContainedDiags);64 65 /// Registers this with the Preprocessor \p PP, must be called before this66 /// 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 the71 /// inclusion directive, otherwise uses quotes.72 /// Returns ``std::nullopt`` on error or if the inclusion directive already73 /// 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 the79 /// inclusion directive, otherwise uses quotes.80 /// Returns ``std::nullopt`` on error or if the inclusion directive already81 /// exists.82 std::optional<FixItHint>83 createMainFileIncludeInsertion(llvm::StringRef Header);84 85 IncludeSorter::IncludeStyle getStyle() const { return Style; }86 87private: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::utils102} // namespace clang103#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_INCLUDEINSERTER_H104