brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.0 KiB · 4c97c5b Raw
357 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_CLANGTIDYOPTIONS_H10#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYOPTIONS_H11 12#include "clang/Basic/DiagnosticIDs.h"13#include "llvm/ADT/IntrusiveRefCntPtr.h"14#include "llvm/ADT/SmallString.h"15#include "llvm/ADT/StringMap.h"16#include "llvm/ADT/StringRef.h"17#include "llvm/Support/ErrorOr.h"18#include "llvm/Support/MemoryBufferRef.h"19#include "llvm/Support/VirtualFileSystem.h"20#include <functional>21#include <optional>22#include <string>23#include <system_error>24#include <utility>25#include <vector>26 27namespace clang::tidy {28 29/// Contains a list of line ranges in a single file.30struct FileFilter {31  /// File name.32  std::string Name;33 34  /// LineRange is a pair<start, end> (inclusive).35  using LineRange = std::pair<unsigned int, unsigned int>;36 37  /// A list of line ranges in this file, for which we show warnings.38  std::vector<LineRange> LineRanges;39};40 41/// Global options. These options are neither stored nor read from42/// configuration files.43struct ClangTidyGlobalOptions {44  /// Output warnings from certain line ranges of certain files only.45  /// If empty, no warnings will be filtered.46  std::vector<FileFilter> LineFilter;47};48 49/// Contains options for clang-tidy. These options may be read from50/// configuration files, and may be different for different translation units.51struct ClangTidyOptions {52  /// These options are used for all settings that haven't been53  /// overridden by the \c OptionsProvider.54  ///55  /// Allow no checks and no headers by default. This method initializes56  /// check-specific options by calling \c ClangTidyModule::getModuleOptions()57  /// of each registered \c ClangTidyModule.58  static ClangTidyOptions getDefaults();59 60  /// Overwrites all fields in here by the fields of \p Other that have a value.61  /// \p Order specifies precedence of \p Other option.62  ClangTidyOptions &mergeWith(const ClangTidyOptions &Other, unsigned Order);63 64  /// Creates a new \c ClangTidyOptions instance combined from all fields65  /// of this instance overridden by the fields of \p Other that have a value.66  /// \p Order specifies precedence of \p Other option.67  [[nodiscard]] ClangTidyOptions merge(const ClangTidyOptions &Other,68                                       unsigned Order) const;69 70  /// Checks filter.71  std::optional<std::string> Checks;72 73  /// WarningsAsErrors filter.74  std::optional<std::string> WarningsAsErrors;75 76  /// File extensions to consider to determine if a given diagnostic is located77  /// in a header file.78  std::optional<std::vector<std::string>> HeaderFileExtensions;79 80  /// File extensions to consider to determine if a given diagnostic is located81  /// is located in an implementation file.82  std::optional<std::vector<std::string>> ImplementationFileExtensions;83 84  /// Output warnings from headers matching this filter. Warnings from85  /// main files will always be displayed.86  std::optional<std::string> HeaderFilterRegex;87 88  /// \brief Exclude warnings from headers matching this filter, even if they89  /// match \c HeaderFilterRegex.90  std::optional<std::string> ExcludeHeaderFilterRegex;91 92  /// Output warnings from system headers matching \c HeaderFilterRegex.93  std::optional<bool> SystemHeaders;94 95  /// Format code around applied fixes with clang-format using this96  /// style.97  ///98  /// Can be one of:99  ///   * 'none' - don't format code around applied fixes;100  ///   * 'llvm', 'google', 'mozilla' or other predefined clang-format style101  ///     names;102  ///   * 'file' - use the .clang-format file in the closest parent directory of103  ///     each source file;104  ///   * '{inline-formatting-style-in-yaml-format}'.105  ///106  /// See clang-format documentation for more about configuring format style.107  std::optional<std::string> FormatStyle;108 109  /// Specifies the name or e-mail of the user running clang-tidy.110  ///111  /// This option is used, for example, to place the correct user name in TODO()112  /// comments in the relevant check.113  std::optional<std::string> User;114 115  /// Helper structure for storing option value with priority of the value.116  struct ClangTidyValue {117    ClangTidyValue() = default;118    ClangTidyValue(const char *Value) : Value(Value) {}119    ClangTidyValue(llvm::StringRef Value, unsigned Priority = 0)120        : Value(Value), Priority(Priority) {}121 122    std::string Value;123    /// Priority stores relative precedence of the value loaded from config124    /// files to disambiguate local vs global value from different levels.125    unsigned Priority = 0;126  };127  using StringPair = std::pair<std::string, std::string>;128  using OptionMap = llvm::StringMap<ClangTidyValue>;129 130  /// Key-value mapping used to store check-specific options.131  OptionMap CheckOptions;132 133  struct CustomCheckDiag {134    std::string BindName;135    std::string Message;136    std::optional<DiagnosticIDs::Level> Level;137  };138  struct CustomCheckValue {139    std::string Name;140    std::string Query;141    llvm::SmallVector<CustomCheckDiag> Diags;142  };143  using CustomCheckValueList = llvm::SmallVector<CustomCheckValue>;144  std::optional<CustomCheckValueList> CustomChecks;145 146  using ArgList = std::vector<std::string>;147 148  /// Add extra compilation arguments to the end of the list.149  std::optional<ArgList> ExtraArgs;150 151  /// Add extra compilation arguments to the start of the list.152  std::optional<ArgList> ExtraArgsBefore;153 154  /// Only used in the FileOptionsProvider and ConfigOptionsProvider. If true155  /// and using a FileOptionsProvider, it will take a configuration file in the156  /// parent directory (if any exists) and apply this config file on top of the157  /// parent one. IF true and using a ConfigOptionsProvider, it will apply this158  /// config on top of any configuration file it finds in the directory using159  /// the same logic as FileOptionsProvider. If false or missing, only this160  /// configuration file will be used.161  std::optional<bool> InheritParentConfig;162 163  /// Use colors in diagnostics. If missing, it will be auto detected.164  std::optional<bool> UseColor;165};166 167/// Abstract interface for retrieving various ClangTidy options.168class ClangTidyOptionsProvider {169public:170  static const char OptionsSourceTypeDefaultBinary[];171  static const char OptionsSourceTypeCheckCommandLineOption[];172  static const char OptionsSourceTypeConfigCommandLineOption[];173 174  virtual ~ClangTidyOptionsProvider() = default;175 176  /// Returns global options, which are independent of the file.177  virtual const ClangTidyGlobalOptions &getGlobalOptions() = 0;178 179  /// ClangTidyOptions and its source.180  //181  /// clang-tidy has 3 types of the sources in order of increasing priority:182  ///    * clang-tidy binary.183  ///    * '-config' commandline option or a specific configuration file. If the184  ///       commandline option is specified, clang-tidy will ignore the185  ///       configuration file.186  ///    * '-checks' commandline option.187  using OptionsSource = std::pair<ClangTidyOptions, std::string>;188 189  /// Returns an ordered vector of OptionsSources, in order of increasing190  /// priority.191  virtual std::vector<OptionsSource>192  getRawOptions(llvm::StringRef FileName) = 0;193 194  /// Returns options applying to a specific translation unit with the195  /// specified \p FileName.196  ClangTidyOptions getOptions(llvm::StringRef FileName);197};198 199/// Implementation of the \c ClangTidyOptionsProvider interface, which200/// returns the same options for all files.201class DefaultOptionsProvider : public ClangTidyOptionsProvider {202public:203  DefaultOptionsProvider(ClangTidyGlobalOptions GlobalOptions,204                         ClangTidyOptions Options)205      : GlobalOptions(std::move(GlobalOptions)),206        DefaultOptions(std::move(Options)) {}207  const ClangTidyGlobalOptions &getGlobalOptions() override {208    return GlobalOptions;209  }210  std::vector<OptionsSource> getRawOptions(llvm::StringRef FileName) override;211 212private:213  ClangTidyGlobalOptions GlobalOptions;214  ClangTidyOptions DefaultOptions;215};216 217class FileOptionsBaseProvider : public DefaultOptionsProvider {218protected:219  // A pair of configuration file base name and a function parsing220  // configuration from text in the corresponding format.221  using ConfigFileHandler =222      std::pair<std::string, std::function<llvm::ErrorOr<ClangTidyOptions>(223                                 llvm::MemoryBufferRef)>>;224 225  /// Configuration file handlers listed in the order of priority.226  ///227  /// Custom configuration file formats can be supported by constructing the228  /// list of handlers and passing it to the appropriate \c FileOptionsProvider229  /// constructor. E.g. initialization of a \c FileOptionsProvider with support230  /// of a custom configuration file format for files named ".my-tidy-config"231  /// could look similar to this:232  /// \code233  /// FileOptionsProvider::ConfigFileHandlers ConfigHandlers;234  /// ConfigHandlers.emplace_back(".my-tidy-config", parseMyConfigFormat);235  /// ConfigHandlers.emplace_back(".clang-tidy", parseConfiguration);236  /// return std::make_unique<FileOptionsProvider>(237  ///     GlobalOptions, DefaultOptions, OverrideOptions, ConfigHandlers);238  /// \endcode239  ///240  /// With the order of handlers shown above, the ".my-tidy-config" file would241  /// take precedence over ".clang-tidy" if both reside in the same directory.242  using ConfigFileHandlers = std::vector<ConfigFileHandler>;243 244  FileOptionsBaseProvider(ClangTidyGlobalOptions GlobalOptions,245                          ClangTidyOptions DefaultOptions,246                          ClangTidyOptions OverrideOptions,247                          llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS);248 249  FileOptionsBaseProvider(ClangTidyGlobalOptions GlobalOptions,250                          ClangTidyOptions DefaultOptions,251                          ClangTidyOptions OverrideOptions,252                          ConfigFileHandlers ConfigHandlers);253 254  void addRawFileOptions(llvm::StringRef AbsolutePath,255                         std::vector<OptionsSource> &CurOptions);256 257  llvm::ErrorOr<llvm::SmallString<128>>258  getNormalizedAbsolutePath(llvm::StringRef AbsolutePath);259 260  /// Try to read configuration files from \p Directory using registered261  /// \c ConfigHandlers.262  std::optional<OptionsSource> tryReadConfigFile(llvm::StringRef Directory);263 264  struct OptionsCache {265    llvm::StringMap<size_t> Memorized;266    llvm::SmallVector<OptionsSource, 4U> Storage;267  } CachedOptions;268  ClangTidyOptions OverrideOptions;269  ConfigFileHandlers ConfigHandlers;270  llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;271};272 273/// Implementation of ClangTidyOptions interface, which is used for274/// '-config' command-line option.275class ConfigOptionsProvider : public FileOptionsBaseProvider {276public:277  ConfigOptionsProvider(278      ClangTidyGlobalOptions GlobalOptions, ClangTidyOptions DefaultOptions,279      ClangTidyOptions ConfigOptions, ClangTidyOptions OverrideOptions,280      llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = nullptr);281  std::vector<OptionsSource> getRawOptions(llvm::StringRef FileName) override;282 283private:284  ClangTidyOptions ConfigOptions;285};286 287/// Implementation of the \c ClangTidyOptionsProvider interface, which288/// tries to find a configuration file in the closest parent directory of each289/// source file.290///291/// By default, files named ".clang-tidy" will be considered, and the292/// \c clang::tidy::parseConfiguration function will be used for parsing, but a293/// custom set of configuration file names and parsing functions can be294/// specified using the appropriate constructor.295class FileOptionsProvider : public FileOptionsBaseProvider {296public:297  /// Initializes the \c FileOptionsProvider instance.298  ///299  /// \param GlobalOptions are just stored and returned to the caller of300  /// \c getGlobalOptions.301  ///302  /// \param DefaultOptions are used for all settings not specified in a303  /// configuration file.304  ///305  /// If any of the \param OverrideOptions fields are set, they will override306  /// whatever options are read from the configuration file.307  FileOptionsProvider(308      ClangTidyGlobalOptions GlobalOptions, ClangTidyOptions DefaultOptions,309      ClangTidyOptions OverrideOptions,310      llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = nullptr);311 312  /// Initializes the \c FileOptionsProvider instance with a custom set313  /// of configuration file handlers.314  ///315  /// \param GlobalOptions are just stored and returned to the caller of316  /// \c getGlobalOptions.317  ///318  /// \param DefaultOptions are used for all settings not specified in a319  /// configuration file.320  ///321  /// If any of the \param OverrideOptions fields are set, they will override322  /// whatever options are read from the configuration file.323  ///324  /// \param ConfigHandlers specifies a custom set of configuration file325  /// handlers. Each handler is a pair of configuration file name and a function326  /// that can parse configuration from this file type. The configuration files327  /// in each directory are searched for in the order of appearance in328  /// \p ConfigHandlers.329  FileOptionsProvider(ClangTidyGlobalOptions GlobalOptions,330                      ClangTidyOptions DefaultOptions,331                      ClangTidyOptions OverrideOptions,332                      ConfigFileHandlers ConfigHandlers);333 334  std::vector<OptionsSource> getRawOptions(llvm::StringRef FileName) override;335};336 337/// Parses LineFilter from JSON and stores it to the \p Options.338std::error_code parseLineFilter(llvm::StringRef LineFilter,339                                ClangTidyGlobalOptions &Options);340 341/// Parses configuration from JSON and returns \c ClangTidyOptions or an342/// error.343llvm::ErrorOr<ClangTidyOptions>344parseConfiguration(llvm::MemoryBufferRef Config);345 346using DiagCallback = llvm::function_ref<void(const llvm::SMDiagnostic &)>;347 348llvm::ErrorOr<ClangTidyOptions>349parseConfigurationWithDiags(llvm::MemoryBufferRef Config, DiagCallback Handler);350 351/// Serializes configuration to a YAML-encoded string.352std::string configurationAsText(const ClangTidyOptions &Options);353 354} // namespace clang::tidy355 356#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYOPTIONS_H357