| //===--- ClangTidyOptions.h - clang-tidy ------------------------*- 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_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYOPTIONS_H | 
 | #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYOPTIONS_H | 
 |  | 
 | #include "llvm/ADT/IntrusiveRefCntPtr.h" | 
 | #include "llvm/ADT/SmallString.h" | 
 | #include "llvm/ADT/StringMap.h" | 
 | #include "llvm/ADT/StringRef.h" | 
 | #include "llvm/Support/ErrorOr.h" | 
 | #include "llvm/Support/MemoryBufferRef.h" | 
 | #include "llvm/Support/VirtualFileSystem.h" | 
 | #include <functional> | 
 | #include <optional> | 
 | #include <string> | 
 | #include <system_error> | 
 | #include <utility> | 
 | #include <vector> | 
 |  | 
 | namespace clang::tidy { | 
 |  | 
 | /// Contains a list of line ranges in a single file. | 
 | struct FileFilter { | 
 |   /// File name. | 
 |   std::string Name; | 
 |  | 
 |   /// LineRange is a pair<start, end> (inclusive). | 
 |   using LineRange = std::pair<unsigned int, unsigned int>; | 
 |  | 
 |   /// A list of line ranges in this file, for which we show warnings. | 
 |   std::vector<LineRange> LineRanges; | 
 | }; | 
 |  | 
 | /// Global options. These options are neither stored nor read from | 
 | /// configuration files. | 
 | struct ClangTidyGlobalOptions { | 
 |   /// Output warnings from certain line ranges of certain files only. | 
 |   /// If empty, no warnings will be filtered. | 
 |   std::vector<FileFilter> LineFilter; | 
 | }; | 
 |  | 
 | /// Contains options for clang-tidy. These options may be read from | 
 | /// configuration files, and may be different for different translation units. | 
 | struct ClangTidyOptions { | 
 |   /// These options are used for all settings that haven't been | 
 |   /// overridden by the \c OptionsProvider. | 
 |   /// | 
 |   /// Allow no checks and no headers by default. This method initializes | 
 |   /// check-specific options by calling \c ClangTidyModule::getModuleOptions() | 
 |   /// of each registered \c ClangTidyModule. | 
 |   static ClangTidyOptions getDefaults(); | 
 |  | 
 |   /// Overwrites all fields in here by the fields of \p Other that have a value. | 
 |   /// \p Order specifies precedence of \p Other option. | 
 |   ClangTidyOptions &mergeWith(const ClangTidyOptions &Other, unsigned Order); | 
 |  | 
 |   /// Creates a new \c ClangTidyOptions instance combined from all fields | 
 |   /// of this instance overridden by the fields of \p Other that have a value. | 
 |   /// \p Order specifies precedence of \p Other option. | 
 |   [[nodiscard]] ClangTidyOptions merge(const ClangTidyOptions &Other, | 
 |                                        unsigned Order) const; | 
 |  | 
 |   /// Checks filter. | 
 |   std::optional<std::string> Checks; | 
 |  | 
 |   /// WarningsAsErrors filter. | 
 |   std::optional<std::string> WarningsAsErrors; | 
 |  | 
 |   /// File extensions to consider to determine if a given diagnostic is located | 
 |   /// in a header file. | 
 |   std::optional<std::vector<std::string>> HeaderFileExtensions; | 
 |  | 
 |   /// File extensions to consider to determine if a given diagnostic is located | 
 |   /// is located in an implementation file. | 
 |   std::optional<std::vector<std::string>> ImplementationFileExtensions; | 
 |  | 
 |   /// Output warnings from headers matching this filter. Warnings from | 
 |   /// main files will always be displayed. | 
 |   std::optional<std::string> HeaderFilterRegex; | 
 |  | 
 |   /// \brief Exclude warnings from headers matching this filter, even if they | 
 |   /// match \c HeaderFilterRegex. | 
 |   std::optional<std::string> ExcludeHeaderFilterRegex; | 
 |  | 
 |   /// Output warnings from system headers matching \c HeaderFilterRegex. | 
 |   std::optional<bool> SystemHeaders; | 
 |  | 
 |   /// Format code around applied fixes with clang-format using this | 
 |   /// style. | 
 |   /// | 
 |   /// Can be one of: | 
 |   ///   * 'none' - don't format code around applied fixes; | 
 |   ///   * 'llvm', 'google', 'mozilla' or other predefined clang-format style | 
 |   ///     names; | 
 |   ///   * 'file' - use the .clang-format file in the closest parent directory of | 
 |   ///     each source file; | 
 |   ///   * '{inline-formatting-style-in-yaml-format}'. | 
 |   /// | 
 |   /// See clang-format documentation for more about configuring format style. | 
 |   std::optional<std::string> FormatStyle; | 
 |  | 
 |   /// Specifies the name or e-mail of the user running clang-tidy. | 
 |   /// | 
 |   /// This option is used, for example, to place the correct user name in TODO() | 
 |   /// comments in the relevant check. | 
 |   std::optional<std::string> User; | 
 |  | 
 |   /// Helper structure for storing option value with priority of the value. | 
 |   struct ClangTidyValue { | 
 |     ClangTidyValue() = default; | 
 |     ClangTidyValue(const char *Value) : Value(Value) {} | 
 |     ClangTidyValue(llvm::StringRef Value, unsigned Priority = 0) | 
 |         : Value(Value), Priority(Priority) {} | 
 |  | 
 |     std::string Value; | 
 |     /// Priority stores relative precedence of the value loaded from config | 
 |     /// files to disambiguate local vs global value from different levels. | 
 |     unsigned Priority = 0; | 
 |   }; | 
 |   using StringPair = std::pair<std::string, std::string>; | 
 |   using OptionMap = llvm::StringMap<ClangTidyValue>; | 
 |  | 
 |   /// Key-value mapping used to store check-specific options. | 
 |   OptionMap CheckOptions; | 
 |  | 
 |   using ArgList = std::vector<std::string>; | 
 |  | 
 |   /// Add extra compilation arguments to the end of the list. | 
 |   std::optional<ArgList> ExtraArgs; | 
 |  | 
 |   /// Add extra compilation arguments to the start of the list. | 
 |   std::optional<ArgList> ExtraArgsBefore; | 
 |  | 
 |   /// Only used in the FileOptionsProvider and ConfigOptionsProvider. If true | 
 |   /// and using a FileOptionsProvider, it will take a configuration file in the | 
 |   /// parent directory (if any exists) and apply this config file on top of the | 
 |   /// parent one. IF true and using a ConfigOptionsProvider, it will apply this | 
 |   /// config on top of any configuration file it finds in the directory using | 
 |   /// the same logic as FileOptionsProvider. If false or missing, only this | 
 |   /// configuration file will be used. | 
 |   std::optional<bool> InheritParentConfig; | 
 |  | 
 |   /// Use colors in diagnostics. If missing, it will be auto detected. | 
 |   std::optional<bool> UseColor; | 
 | }; | 
 |  | 
 | /// Abstract interface for retrieving various ClangTidy options. | 
 | class ClangTidyOptionsProvider { | 
 | public: | 
 |   static const char OptionsSourceTypeDefaultBinary[]; | 
 |   static const char OptionsSourceTypeCheckCommandLineOption[]; | 
 |   static const char OptionsSourceTypeConfigCommandLineOption[]; | 
 |  | 
 |   virtual ~ClangTidyOptionsProvider() {} | 
 |  | 
 |   /// Returns global options, which are independent of the file. | 
 |   virtual const ClangTidyGlobalOptions &getGlobalOptions() = 0; | 
 |  | 
 |   /// ClangTidyOptions and its source. | 
 |   // | 
 |   /// clang-tidy has 3 types of the sources in order of increasing priority: | 
 |   ///    * clang-tidy binary. | 
 |   ///    * '-config' commandline option or a specific configuration file. If the | 
 |   ///       commandline option is specified, clang-tidy will ignore the | 
 |   ///       configuration file. | 
 |   ///    * '-checks' commandline option. | 
 |   using OptionsSource = std::pair<ClangTidyOptions, std::string>; | 
 |  | 
 |   /// Returns an ordered vector of OptionsSources, in order of increasing | 
 |   /// priority. | 
 |   virtual std::vector<OptionsSource> | 
 |   getRawOptions(llvm::StringRef FileName) = 0; | 
 |  | 
 |   /// Returns options applying to a specific translation unit with the | 
 |   /// specified \p FileName. | 
 |   ClangTidyOptions getOptions(llvm::StringRef FileName); | 
 | }; | 
 |  | 
 | /// Implementation of the \c ClangTidyOptionsProvider interface, which | 
 | /// returns the same options for all files. | 
 | class DefaultOptionsProvider : public ClangTidyOptionsProvider { | 
 | public: | 
 |   DefaultOptionsProvider(ClangTidyGlobalOptions GlobalOptions, | 
 |                          ClangTidyOptions Options) | 
 |       : GlobalOptions(std::move(GlobalOptions)), | 
 |         DefaultOptions(std::move(Options)) {} | 
 |   const ClangTidyGlobalOptions &getGlobalOptions() override { | 
 |     return GlobalOptions; | 
 |   } | 
 |   std::vector<OptionsSource> getRawOptions(llvm::StringRef FileName) override; | 
 |  | 
 | private: | 
 |   ClangTidyGlobalOptions GlobalOptions; | 
 |   ClangTidyOptions DefaultOptions; | 
 | }; | 
 |  | 
 | class FileOptionsBaseProvider : public DefaultOptionsProvider { | 
 | protected: | 
 |   // A pair of configuration file base name and a function parsing | 
 |   // configuration from text in the corresponding format. | 
 |   using ConfigFileHandler = | 
 |       std::pair<std::string, std::function<llvm::ErrorOr<ClangTidyOptions>( | 
 |                                  llvm::MemoryBufferRef)>>; | 
 |  | 
 |   /// Configuration file handlers listed in the order of priority. | 
 |   /// | 
 |   /// Custom configuration file formats can be supported by constructing the | 
 |   /// list of handlers and passing it to the appropriate \c FileOptionsProvider | 
 |   /// constructor. E.g. initialization of a \c FileOptionsProvider with support | 
 |   /// of a custom configuration file format for files named ".my-tidy-config" | 
 |   /// could look similar to this: | 
 |   /// \code | 
 |   /// FileOptionsProvider::ConfigFileHandlers ConfigHandlers; | 
 |   /// ConfigHandlers.emplace_back(".my-tidy-config", parseMyConfigFormat); | 
 |   /// ConfigHandlers.emplace_back(".clang-tidy", parseConfiguration); | 
 |   /// return std::make_unique<FileOptionsProvider>( | 
 |   ///     GlobalOptions, DefaultOptions, OverrideOptions, ConfigHandlers); | 
 |   /// \endcode | 
 |   /// | 
 |   /// With the order of handlers shown above, the ".my-tidy-config" file would | 
 |   /// take precedence over ".clang-tidy" if both reside in the same directory. | 
 |   using ConfigFileHandlers = std::vector<ConfigFileHandler>; | 
 |  | 
 |   FileOptionsBaseProvider(ClangTidyGlobalOptions GlobalOptions, | 
 |                           ClangTidyOptions DefaultOptions, | 
 |                           ClangTidyOptions OverrideOptions, | 
 |                           llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS); | 
 |  | 
 |   FileOptionsBaseProvider(ClangTidyGlobalOptions GlobalOptions, | 
 |                           ClangTidyOptions DefaultOptions, | 
 |                           ClangTidyOptions OverrideOptions, | 
 |                           ConfigFileHandlers ConfigHandlers); | 
 |  | 
 |   void addRawFileOptions(llvm::StringRef AbsolutePath, | 
 |                          std::vector<OptionsSource> &CurOptions); | 
 |  | 
 |   llvm::ErrorOr<llvm::SmallString<128>> | 
 |   getNormalizedAbsolutePath(llvm::StringRef AbsolutePath); | 
 |  | 
 |   /// Try to read configuration files from \p Directory using registered | 
 |   /// \c ConfigHandlers. | 
 |   std::optional<OptionsSource> tryReadConfigFile(llvm::StringRef Directory); | 
 |  | 
 |   struct OptionsCache { | 
 |     llvm::StringMap<size_t> Memorized; | 
 |     llvm::SmallVector<OptionsSource, 4U> Storage; | 
 |   } CachedOptions; | 
 |   ClangTidyOptions OverrideOptions; | 
 |   ConfigFileHandlers ConfigHandlers; | 
 |   llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS; | 
 | }; | 
 |  | 
 | /// Implementation of ClangTidyOptions interface, which is used for | 
 | /// '-config' command-line option. | 
 | class ConfigOptionsProvider : public FileOptionsBaseProvider { | 
 | public: | 
 |   ConfigOptionsProvider( | 
 |       ClangTidyGlobalOptions GlobalOptions, ClangTidyOptions DefaultOptions, | 
 |       ClangTidyOptions ConfigOptions, ClangTidyOptions OverrideOptions, | 
 |       llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = nullptr); | 
 |   std::vector<OptionsSource> getRawOptions(llvm::StringRef FileName) override; | 
 |  | 
 | private: | 
 |   ClangTidyOptions ConfigOptions; | 
 | }; | 
 |  | 
 | /// Implementation of the \c ClangTidyOptionsProvider interface, which | 
 | /// tries to find a configuration file in the closest parent directory of each | 
 | /// source file. | 
 | /// | 
 | /// By default, files named ".clang-tidy" will be considered, and the | 
 | /// \c clang::tidy::parseConfiguration function will be used for parsing, but a | 
 | /// custom set of configuration file names and parsing functions can be | 
 | /// specified using the appropriate constructor. | 
 | class FileOptionsProvider : public FileOptionsBaseProvider { | 
 | public: | 
 |   /// Initializes the \c FileOptionsProvider instance. | 
 |   /// | 
 |   /// \param GlobalOptions are just stored and returned to the caller of | 
 |   /// \c getGlobalOptions. | 
 |   /// | 
 |   /// \param DefaultOptions are used for all settings not specified in a | 
 |   /// configuration file. | 
 |   /// | 
 |   /// If any of the \param OverrideOptions fields are set, they will override | 
 |   /// whatever options are read from the configuration file. | 
 |   FileOptionsProvider( | 
 |       ClangTidyGlobalOptions GlobalOptions, ClangTidyOptions DefaultOptions, | 
 |       ClangTidyOptions OverrideOptions, | 
 |       llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = nullptr); | 
 |  | 
 |   /// Initializes the \c FileOptionsProvider instance with a custom set | 
 |   /// of configuration file handlers. | 
 |   /// | 
 |   /// \param GlobalOptions are just stored and returned to the caller of | 
 |   /// \c getGlobalOptions. | 
 |   /// | 
 |   /// \param DefaultOptions are used for all settings not specified in a | 
 |   /// configuration file. | 
 |   /// | 
 |   /// If any of the \param OverrideOptions fields are set, they will override | 
 |   /// whatever options are read from the configuration file. | 
 |   /// | 
 |   /// \param ConfigHandlers specifies a custom set of configuration file | 
 |   /// handlers. Each handler is a pair of configuration file name and a function | 
 |   /// that can parse configuration from this file type. The configuration files | 
 |   /// in each directory are searched for in the order of appearance in | 
 |   /// \p ConfigHandlers. | 
 |   FileOptionsProvider(ClangTidyGlobalOptions GlobalOptions, | 
 |                       ClangTidyOptions DefaultOptions, | 
 |                       ClangTidyOptions OverrideOptions, | 
 |                       ConfigFileHandlers ConfigHandlers); | 
 |  | 
 |   std::vector<OptionsSource> getRawOptions(llvm::StringRef FileName) override; | 
 | }; | 
 |  | 
 | /// Parses LineFilter from JSON and stores it to the \p Options. | 
 | std::error_code parseLineFilter(llvm::StringRef LineFilter, | 
 |                                 ClangTidyGlobalOptions &Options); | 
 |  | 
 | /// Parses configuration from JSON and returns \c ClangTidyOptions or an | 
 | /// error. | 
 | llvm::ErrorOr<ClangTidyOptions> | 
 | parseConfiguration(llvm::MemoryBufferRef Config); | 
 |  | 
 | using DiagCallback = llvm::function_ref<void(const llvm::SMDiagnostic &)>; | 
 |  | 
 | llvm::ErrorOr<ClangTidyOptions> | 
 | parseConfigurationWithDiags(llvm::MemoryBufferRef Config, DiagCallback Handler); | 
 |  | 
 | /// Serializes configuration to a YAML-encoded string. | 
 | std::string configurationAsText(const ClangTidyOptions &Options); | 
 |  | 
 | } // namespace clang::tidy | 
 |  | 
 | #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYOPTIONS_H |