1 //===--- ClangTidyOptions.h - clang-tidy ------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYOPTIONS_H 11 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYOPTIONS_H 12 13 #include "llvm/ADT/Optional.h" 14 #include "llvm/ADT/StringMap.h" 15 #include "llvm/ADT/StringRef.h" 16 #include "llvm/ADT/IntrusiveRefCntPtr.h" 17 #include "llvm/Support/ErrorOr.h" 18 #include "clang/Basic/VirtualFileSystem.h" 19 #include <functional> 20 #include <map> 21 #include <string> 22 #include <system_error> 23 #include <utility> 24 #include <vector> 25 26 namespace clang { 27 namespace tidy { 28 29 /// \brief Contains a list of line ranges in a single file. 30 struct FileFilter { 31 /// \brief File name. 32 std::string Name; 33 34 /// \brief LineRange is a pair<start, end> (inclusive). 35 typedef std::pair<unsigned, unsigned> LineRange; 36 37 /// \brief A list of line ranges in this file, for which we show warnings. 38 std::vector<LineRange> LineRanges; 39 }; 40 41 /// \brief Global options. These options are neither stored nor read from 42 /// configuration files. 43 struct ClangTidyGlobalOptions { 44 /// \brief 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 /// \brief Contains options for clang-tidy. These options may be read from 50 /// configuration files, and may be different for different translation units. 51 struct ClangTidyOptions { 52 /// \brief These options are used for all settings that haven't been 53 /// overridden by the \c OptionsProvider. 54 /// 55 /// Allow no checks and no headers by default. This method initializes 56 /// check-specific options by calling \c ClangTidyModule::getModuleOptions() 57 /// of each registered \c ClangTidyModule. 58 static ClangTidyOptions getDefaults(); 59 60 /// \brief Creates a new \c ClangTidyOptions instance combined from all fields 61 /// of this instance overridden by the fields of \p Other that have a value. 62 ClangTidyOptions mergeWith(const ClangTidyOptions &Other) const; 63 64 /// \brief Checks filter. 65 llvm::Optional<std::string> Checks; 66 67 /// \brief WarningsAsErrors filter. 68 llvm::Optional<std::string> WarningsAsErrors; 69 70 /// \brief Output warnings from headers matching this filter. Warnings from 71 /// main files will always be displayed. 72 llvm::Optional<std::string> HeaderFilterRegex; 73 74 /// \brief Output warnings from system headers matching \c HeaderFilterRegex. 75 llvm::Optional<bool> SystemHeaders; 76 77 /// \brief Format code around applied fixes with clang-format using this 78 /// style. 79 /// 80 /// Can be one of: 81 /// * 'none' - don't format code around applied fixes; 82 /// * 'llvm', 'google', 'mozilla' or other predefined clang-format style 83 /// names; 84 /// * 'file' - use the .clang-format file in the closest parent directory of 85 /// each source file; 86 /// * '{inline-formatting-style-in-yaml-format}'. 87 /// 88 /// See clang-format documentation for more about configuring format style. 89 llvm::Optional<std::string> FormatStyle; 90 91 /// \brief Specifies the name or e-mail of the user running clang-tidy. 92 /// 93 /// This option is used, for example, to place the correct user name in TODO() 94 /// comments in the relevant check. 95 llvm::Optional<std::string> User; 96 97 typedef std::pair<std::string, std::string> StringPair; 98 typedef std::map<std::string, std::string> OptionMap; 99 100 /// \brief Key-value mapping used to store check-specific options. 101 OptionMap CheckOptions; 102 103 typedef std::vector<std::string> ArgList; 104 105 /// \brief Add extra compilation arguments to the end of the list. 106 llvm::Optional<ArgList> ExtraArgs; 107 108 /// \brief Add extra compilation arguments to the start of the list. 109 llvm::Optional<ArgList> ExtraArgsBefore; 110 }; 111 112 /// \brief Abstract interface for retrieving various ClangTidy options. 113 class ClangTidyOptionsProvider { 114 public: 115 static const char OptionsSourceTypeDefaultBinary[]; 116 static const char OptionsSourceTypeCheckCommandLineOption[]; 117 static const char OptionsSourceTypeConfigCommandLineOption[]; 118 ~ClangTidyOptionsProvider()119 virtual ~ClangTidyOptionsProvider() {} 120 121 /// \brief Returns global options, which are independent of the file. 122 virtual const ClangTidyGlobalOptions &getGlobalOptions() = 0; 123 124 /// \brief ClangTidyOptions and its source. 125 // 126 /// clang-tidy has 3 types of the sources in order of increasing priority: 127 /// * clang-tidy binary. 128 /// * '-config' commandline option or a specific configuration file. If the 129 /// commandline option is specified, clang-tidy will ignore the 130 /// configuration file. 131 /// * '-checks' commandline option. 132 typedef std::pair<ClangTidyOptions, std::string> OptionsSource; 133 134 /// \brief Returns an ordered vector of OptionsSources, in order of increasing 135 /// priority. 136 virtual std::vector<OptionsSource> 137 getRawOptions(llvm::StringRef FileName) = 0; 138 139 /// \brief Returns options applying to a specific translation unit with the 140 /// specified \p FileName. 141 ClangTidyOptions getOptions(llvm::StringRef FileName); 142 }; 143 144 /// \brief Implementation of the \c ClangTidyOptionsProvider interface, which 145 /// returns the same options for all files. 146 class DefaultOptionsProvider : public ClangTidyOptionsProvider { 147 public: DefaultOptionsProvider(const ClangTidyGlobalOptions & GlobalOptions,const ClangTidyOptions & Options)148 DefaultOptionsProvider(const ClangTidyGlobalOptions &GlobalOptions, 149 const ClangTidyOptions &Options) 150 : GlobalOptions(GlobalOptions), DefaultOptions(Options) {} getGlobalOptions()151 const ClangTidyGlobalOptions &getGlobalOptions() override { 152 return GlobalOptions; 153 } 154 std::vector<OptionsSource> getRawOptions(llvm::StringRef FileName) override; 155 156 private: 157 ClangTidyGlobalOptions GlobalOptions; 158 ClangTidyOptions DefaultOptions; 159 }; 160 161 /// \brief Implementation of ClangTidyOptions interface, which is used for 162 /// '-config' command-line option. 163 class ConfigOptionsProvider : public DefaultOptionsProvider { 164 public: 165 ConfigOptionsProvider(const ClangTidyGlobalOptions &GlobalOptions, 166 const ClangTidyOptions &DefaultOptions, 167 const ClangTidyOptions &ConfigOptions, 168 const ClangTidyOptions &OverrideOptions); 169 std::vector<OptionsSource> getRawOptions(llvm::StringRef FileName) override; 170 171 private: 172 ClangTidyOptions ConfigOptions; 173 ClangTidyOptions OverrideOptions; 174 }; 175 176 /// \brief Implementation of the \c ClangTidyOptionsProvider interface, which 177 /// tries to find a configuration file in the closest parent directory of each 178 /// source file. 179 /// 180 /// By default, files named ".clang-tidy" will be considered, and the 181 /// \c clang::tidy::parseConfiguration function will be used for parsing, but a 182 /// custom set of configuration file names and parsing functions can be 183 /// specified using the appropriate constructor. 184 class FileOptionsProvider : public DefaultOptionsProvider { 185 public: 186 // \brief A pair of configuration file base name and a function parsing 187 // configuration from text in the corresponding format. 188 typedef std::pair<std::string, std::function<llvm::ErrorOr<ClangTidyOptions>( 189 llvm::StringRef)>> 190 ConfigFileHandler; 191 192 /// \brief Configuration file handlers listed in the order of priority. 193 /// 194 /// Custom configuration file formats can be supported by constructing the 195 /// list of handlers and passing it to the appropriate \c FileOptionsProvider 196 /// constructor. E.g. initialization of a \c FileOptionsProvider with support 197 /// of a custom configuration file format for files named ".my-tidy-config" 198 /// could look similar to this: 199 /// \code 200 /// FileOptionsProvider::ConfigFileHandlers ConfigHandlers; 201 /// ConfigHandlers.emplace_back(".my-tidy-config", parseMyConfigFormat); 202 /// ConfigHandlers.emplace_back(".clang-tidy", parseConfiguration); 203 /// return llvm::make_unique<FileOptionsProvider>( 204 /// GlobalOptions, DefaultOptions, OverrideOptions, ConfigHandlers); 205 /// \endcode 206 /// 207 /// With the order of handlers shown above, the ".my-tidy-config" file would 208 /// take precedence over ".clang-tidy" if both reside in the same directory. 209 typedef std::vector<ConfigFileHandler> ConfigFileHandlers; 210 211 /// \brief Initializes the \c FileOptionsProvider instance. 212 /// 213 /// \param GlobalOptions are just stored and returned to the caller of 214 /// \c getGlobalOptions. 215 /// 216 /// \param DefaultOptions are used for all settings not specified in a 217 /// configuration file. 218 /// 219 /// If any of the \param OverrideOptions fields are set, they will override 220 /// whatever options are read from the configuration file. 221 FileOptionsProvider(const ClangTidyGlobalOptions &GlobalOptions, 222 const ClangTidyOptions &DefaultOptions, 223 const ClangTidyOptions &OverrideOptions, 224 llvm::IntrusiveRefCntPtr<vfs::FileSystem> FS = nullptr); 225 226 /// \brief Initializes the \c FileOptionsProvider instance with a custom set 227 /// of configuration file handlers. 228 /// 229 /// \param GlobalOptions are just stored and returned to the caller of 230 /// \c getGlobalOptions. 231 /// 232 /// \param DefaultOptions are used for all settings not specified in a 233 /// configuration file. 234 /// 235 /// If any of the \param OverrideOptions fields are set, they will override 236 /// whatever options are read from the configuration file. 237 /// 238 /// \param ConfigHandlers specifies a custom set of configuration file 239 /// handlers. Each handler is a pair of configuration file name and a function 240 /// that can parse configuration from this file type. The configuration files 241 /// in each directory are searched for in the order of appearance in 242 /// \p ConfigHandlers. 243 FileOptionsProvider(const ClangTidyGlobalOptions &GlobalOptions, 244 const ClangTidyOptions &DefaultOptions, 245 const ClangTidyOptions &OverrideOptions, 246 const ConfigFileHandlers &ConfigHandlers); 247 248 std::vector<OptionsSource> getRawOptions(llvm::StringRef FileName) override; 249 250 protected: 251 /// \brief Try to read configuration files from \p Directory using registered 252 /// \c ConfigHandlers. 253 llvm::Optional<OptionsSource> tryReadConfigFile(llvm::StringRef Directory); 254 255 llvm::StringMap<OptionsSource> CachedOptions; 256 ClangTidyOptions OverrideOptions; 257 ConfigFileHandlers ConfigHandlers; 258 llvm::IntrusiveRefCntPtr<vfs::FileSystem> FS; 259 }; 260 261 /// \brief Parses LineFilter from JSON and stores it to the \p Options. 262 std::error_code parseLineFilter(llvm::StringRef LineFilter, 263 ClangTidyGlobalOptions &Options); 264 265 /// \brief Parses configuration from JSON and returns \c ClangTidyOptions or an 266 /// error. 267 llvm::ErrorOr<ClangTidyOptions> parseConfiguration(llvm::StringRef Config); 268 269 /// \brief Serializes configuration to a YAML-encoded string. 270 std::string configurationAsText(const ClangTidyOptions &Options); 271 272 } // end namespace tidy 273 } // end namespace clang 274 275 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYOPTIONS_H 276