Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:23

0001 //===--- ClangTidyOptions.h - clang-tidy ------------------------*- 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_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYOPTIONS_H
0010 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYOPTIONS_H
0011 
0012 #include "llvm/ADT/IntrusiveRefCntPtr.h"
0013 #include "llvm/ADT/SmallString.h"
0014 #include "llvm/ADT/StringMap.h"
0015 #include "llvm/ADT/StringRef.h"
0016 #include "llvm/Support/ErrorOr.h"
0017 #include "llvm/Support/MemoryBufferRef.h"
0018 #include "llvm/Support/VirtualFileSystem.h"
0019 #include <functional>
0020 #include <optional>
0021 #include <string>
0022 #include <system_error>
0023 #include <utility>
0024 #include <vector>
0025 
0026 namespace clang::tidy {
0027 
0028 /// Contains a list of line ranges in a single file.
0029 struct FileFilter {
0030   /// File name.
0031   std::string Name;
0032 
0033   /// LineRange is a pair<start, end> (inclusive).
0034   using LineRange = std::pair<unsigned int, unsigned int>;
0035 
0036   /// A list of line ranges in this file, for which we show warnings.
0037   std::vector<LineRange> LineRanges;
0038 };
0039 
0040 /// Global options. These options are neither stored nor read from
0041 /// configuration files.
0042 struct ClangTidyGlobalOptions {
0043   /// Output warnings from certain line ranges of certain files only.
0044   /// If empty, no warnings will be filtered.
0045   std::vector<FileFilter> LineFilter;
0046 };
0047 
0048 /// Contains options for clang-tidy. These options may be read from
0049 /// configuration files, and may be different for different translation units.
0050 struct ClangTidyOptions {
0051   /// These options are used for all settings that haven't been
0052   /// overridden by the \c OptionsProvider.
0053   ///
0054   /// Allow no checks and no headers by default. This method initializes
0055   /// check-specific options by calling \c ClangTidyModule::getModuleOptions()
0056   /// of each registered \c ClangTidyModule.
0057   static ClangTidyOptions getDefaults();
0058 
0059   /// Overwrites all fields in here by the fields of \p Other that have a value.
0060   /// \p Order specifies precedence of \p Other option.
0061   ClangTidyOptions &mergeWith(const ClangTidyOptions &Other, unsigned Order);
0062 
0063   /// Creates a new \c ClangTidyOptions instance combined from all fields
0064   /// of this instance overridden by the fields of \p Other that have a value.
0065   /// \p Order specifies precedence of \p Other option.
0066   [[nodiscard]] ClangTidyOptions merge(const ClangTidyOptions &Other,
0067                                        unsigned Order) const;
0068 
0069   /// Checks filter.
0070   std::optional<std::string> Checks;
0071 
0072   /// WarningsAsErrors filter.
0073   std::optional<std::string> WarningsAsErrors;
0074 
0075   /// File extensions to consider to determine if a given diagnostic is located
0076   /// in a header file.
0077   std::optional<std::vector<std::string>> HeaderFileExtensions;
0078 
0079   /// File extensions to consider to determine if a given diagnostic is located
0080   /// is located in an implementation file.
0081   std::optional<std::vector<std::string>> ImplementationFileExtensions;
0082 
0083   /// Output warnings from headers matching this filter. Warnings from
0084   /// main files will always be displayed.
0085   std::optional<std::string> HeaderFilterRegex;
0086 
0087   /// \brief Exclude warnings from headers matching this filter, even if they
0088   /// match \c HeaderFilterRegex.
0089   std::optional<std::string> ExcludeHeaderFilterRegex;
0090 
0091   /// Output warnings from system headers matching \c HeaderFilterRegex.
0092   std::optional<bool> SystemHeaders;
0093 
0094   /// Format code around applied fixes with clang-format using this
0095   /// style.
0096   ///
0097   /// Can be one of:
0098   ///   * 'none' - don't format code around applied fixes;
0099   ///   * 'llvm', 'google', 'mozilla' or other predefined clang-format style
0100   ///     names;
0101   ///   * 'file' - use the .clang-format file in the closest parent directory of
0102   ///     each source file;
0103   ///   * '{inline-formatting-style-in-yaml-format}'.
0104   ///
0105   /// See clang-format documentation for more about configuring format style.
0106   std::optional<std::string> FormatStyle;
0107 
0108   /// Specifies the name or e-mail of the user running clang-tidy.
0109   ///
0110   /// This option is used, for example, to place the correct user name in TODO()
0111   /// comments in the relevant check.
0112   std::optional<std::string> User;
0113 
0114   /// Helper structure for storing option value with priority of the value.
0115   struct ClangTidyValue {
0116     ClangTidyValue() = default;
0117     ClangTidyValue(const char *Value) : Value(Value) {}
0118     ClangTidyValue(llvm::StringRef Value, unsigned Priority = 0)
0119         : Value(Value), Priority(Priority) {}
0120 
0121     std::string Value;
0122     /// Priority stores relative precedence of the value loaded from config
0123     /// files to disambiguate local vs global value from different levels.
0124     unsigned Priority = 0;
0125   };
0126   using StringPair = std::pair<std::string, std::string>;
0127   using OptionMap = llvm::StringMap<ClangTidyValue>;
0128 
0129   /// Key-value mapping used to store check-specific options.
0130   OptionMap CheckOptions;
0131 
0132   using ArgList = std::vector<std::string>;
0133 
0134   /// Add extra compilation arguments to the end of the list.
0135   std::optional<ArgList> ExtraArgs;
0136 
0137   /// Add extra compilation arguments to the start of the list.
0138   std::optional<ArgList> ExtraArgsBefore;
0139 
0140   /// Only used in the FileOptionsProvider and ConfigOptionsProvider. If true
0141   /// and using a FileOptionsProvider, it will take a configuration file in the
0142   /// parent directory (if any exists) and apply this config file on top of the
0143   /// parent one. IF true and using a ConfigOptionsProvider, it will apply this
0144   /// config on top of any configuration file it finds in the directory using
0145   /// the same logic as FileOptionsProvider. If false or missing, only this
0146   /// configuration file will be used.
0147   std::optional<bool> InheritParentConfig;
0148 
0149   /// Use colors in diagnostics. If missing, it will be auto detected.
0150   std::optional<bool> UseColor;
0151 };
0152 
0153 /// Abstract interface for retrieving various ClangTidy options.
0154 class ClangTidyOptionsProvider {
0155 public:
0156   static const char OptionsSourceTypeDefaultBinary[];
0157   static const char OptionsSourceTypeCheckCommandLineOption[];
0158   static const char OptionsSourceTypeConfigCommandLineOption[];
0159 
0160   virtual ~ClangTidyOptionsProvider() {}
0161 
0162   /// Returns global options, which are independent of the file.
0163   virtual const ClangTidyGlobalOptions &getGlobalOptions() = 0;
0164 
0165   /// ClangTidyOptions and its source.
0166   //
0167   /// clang-tidy has 3 types of the sources in order of increasing priority:
0168   ///    * clang-tidy binary.
0169   ///    * '-config' commandline option or a specific configuration file. If the
0170   ///       commandline option is specified, clang-tidy will ignore the
0171   ///       configuration file.
0172   ///    * '-checks' commandline option.
0173   using OptionsSource = std::pair<ClangTidyOptions, std::string>;
0174 
0175   /// Returns an ordered vector of OptionsSources, in order of increasing
0176   /// priority.
0177   virtual std::vector<OptionsSource>
0178   getRawOptions(llvm::StringRef FileName) = 0;
0179 
0180   /// Returns options applying to a specific translation unit with the
0181   /// specified \p FileName.
0182   ClangTidyOptions getOptions(llvm::StringRef FileName);
0183 };
0184 
0185 /// Implementation of the \c ClangTidyOptionsProvider interface, which
0186 /// returns the same options for all files.
0187 class DefaultOptionsProvider : public ClangTidyOptionsProvider {
0188 public:
0189   DefaultOptionsProvider(ClangTidyGlobalOptions GlobalOptions,
0190                          ClangTidyOptions Options)
0191       : GlobalOptions(std::move(GlobalOptions)),
0192         DefaultOptions(std::move(Options)) {}
0193   const ClangTidyGlobalOptions &getGlobalOptions() override {
0194     return GlobalOptions;
0195   }
0196   std::vector<OptionsSource> getRawOptions(llvm::StringRef FileName) override;
0197 
0198 private:
0199   ClangTidyGlobalOptions GlobalOptions;
0200   ClangTidyOptions DefaultOptions;
0201 };
0202 
0203 class FileOptionsBaseProvider : public DefaultOptionsProvider {
0204 protected:
0205   // A pair of configuration file base name and a function parsing
0206   // configuration from text in the corresponding format.
0207   using ConfigFileHandler = std::pair<std::string, std::function<llvm::ErrorOr<ClangTidyOptions> (llvm::MemoryBufferRef)>>;
0208 
0209   /// Configuration file handlers listed in the order of priority.
0210   ///
0211   /// Custom configuration file formats can be supported by constructing the
0212   /// list of handlers and passing it to the appropriate \c FileOptionsProvider
0213   /// constructor. E.g. initialization of a \c FileOptionsProvider with support
0214   /// of a custom configuration file format for files named ".my-tidy-config"
0215   /// could look similar to this:
0216   /// \code
0217   /// FileOptionsProvider::ConfigFileHandlers ConfigHandlers;
0218   /// ConfigHandlers.emplace_back(".my-tidy-config", parseMyConfigFormat);
0219   /// ConfigHandlers.emplace_back(".clang-tidy", parseConfiguration);
0220   /// return std::make_unique<FileOptionsProvider>(
0221   ///     GlobalOptions, DefaultOptions, OverrideOptions, ConfigHandlers);
0222   /// \endcode
0223   ///
0224   /// With the order of handlers shown above, the ".my-tidy-config" file would
0225   /// take precedence over ".clang-tidy" if both reside in the same directory.
0226   using ConfigFileHandlers = std::vector<ConfigFileHandler>;
0227 
0228   FileOptionsBaseProvider(ClangTidyGlobalOptions GlobalOptions,
0229                           ClangTidyOptions DefaultOptions,
0230                           ClangTidyOptions OverrideOptions,
0231                           llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS);
0232 
0233   FileOptionsBaseProvider(ClangTidyGlobalOptions GlobalOptions,
0234                           ClangTidyOptions DefaultOptions,
0235                           ClangTidyOptions OverrideOptions,
0236                           ConfigFileHandlers ConfigHandlers);
0237 
0238   void addRawFileOptions(llvm::StringRef AbsolutePath,
0239                          std::vector<OptionsSource> &CurOptions);
0240 
0241   llvm::ErrorOr<llvm::SmallString<128>>
0242   getNormalizedAbsolutePath(llvm::StringRef AbsolutePath);
0243 
0244   /// Try to read configuration files from \p Directory using registered
0245   /// \c ConfigHandlers.
0246   std::optional<OptionsSource> tryReadConfigFile(llvm::StringRef Directory);
0247 
0248   struct OptionsCache {
0249     llvm::StringMap<size_t> Memorized;
0250     llvm::SmallVector<OptionsSource, 4U> Storage;
0251   } CachedOptions;
0252   ClangTidyOptions OverrideOptions;
0253   ConfigFileHandlers ConfigHandlers;
0254   llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
0255 };
0256 
0257 /// Implementation of ClangTidyOptions interface, which is used for
0258 /// '-config' command-line option.
0259 class ConfigOptionsProvider : public FileOptionsBaseProvider {
0260 public:
0261   ConfigOptionsProvider(
0262       ClangTidyGlobalOptions GlobalOptions, ClangTidyOptions DefaultOptions,
0263       ClangTidyOptions ConfigOptions, ClangTidyOptions OverrideOptions,
0264       llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = nullptr);
0265   std::vector<OptionsSource> getRawOptions(llvm::StringRef FileName) override;
0266 
0267 private:
0268   ClangTidyOptions ConfigOptions;
0269 };
0270 
0271 /// Implementation of the \c ClangTidyOptionsProvider interface, which
0272 /// tries to find a configuration file in the closest parent directory of each
0273 /// source file.
0274 ///
0275 /// By default, files named ".clang-tidy" will be considered, and the
0276 /// \c clang::tidy::parseConfiguration function will be used for parsing, but a
0277 /// custom set of configuration file names and parsing functions can be
0278 /// specified using the appropriate constructor.
0279 class FileOptionsProvider : public FileOptionsBaseProvider {
0280 public:
0281   /// Initializes the \c FileOptionsProvider instance.
0282   ///
0283   /// \param GlobalOptions are just stored and returned to the caller of
0284   /// \c getGlobalOptions.
0285   ///
0286   /// \param DefaultOptions are used for all settings not specified in a
0287   /// configuration file.
0288   ///
0289   /// If any of the \param OverrideOptions fields are set, they will override
0290   /// whatever options are read from the configuration file.
0291   FileOptionsProvider(
0292       ClangTidyGlobalOptions GlobalOptions, ClangTidyOptions DefaultOptions,
0293       ClangTidyOptions OverrideOptions,
0294       llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = nullptr);
0295 
0296   /// Initializes the \c FileOptionsProvider instance with a custom set
0297   /// of configuration file handlers.
0298   ///
0299   /// \param GlobalOptions are just stored and returned to the caller of
0300   /// \c getGlobalOptions.
0301   ///
0302   /// \param DefaultOptions are used for all settings not specified in a
0303   /// configuration file.
0304   ///
0305   /// If any of the \param OverrideOptions fields are set, they will override
0306   /// whatever options are read from the configuration file.
0307   ///
0308   /// \param ConfigHandlers specifies a custom set of configuration file
0309   /// handlers. Each handler is a pair of configuration file name and a function
0310   /// that can parse configuration from this file type. The configuration files
0311   /// in each directory are searched for in the order of appearance in
0312   /// \p ConfigHandlers.
0313   FileOptionsProvider(ClangTidyGlobalOptions GlobalOptions,
0314                       ClangTidyOptions DefaultOptions,
0315                       ClangTidyOptions OverrideOptions,
0316                       ConfigFileHandlers ConfigHandlers);
0317 
0318   std::vector<OptionsSource> getRawOptions(llvm::StringRef FileName) override;
0319 };
0320 
0321 /// Parses LineFilter from JSON and stores it to the \p Options.
0322 std::error_code parseLineFilter(llvm::StringRef LineFilter,
0323                                 ClangTidyGlobalOptions &Options);
0324 
0325 /// Parses configuration from JSON and returns \c ClangTidyOptions or an
0326 /// error.
0327 llvm::ErrorOr<ClangTidyOptions>
0328 parseConfiguration(llvm::MemoryBufferRef Config);
0329 
0330 using DiagCallback = llvm::function_ref<void(const llvm::SMDiagnostic &)>;
0331 
0332 llvm::ErrorOr<ClangTidyOptions>
0333 parseConfigurationWithDiags(llvm::MemoryBufferRef Config, DiagCallback Handler);
0334 
0335 /// Serializes configuration to a YAML-encoded string.
0336 std::string configurationAsText(const ClangTidyOptions &Options);
0337 
0338 } // namespace clang::tidy
0339 
0340 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYOPTIONS_H